home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 1
/
CU Amiga Magazine CD-ROM Special Edition (1995)(EMAP Images)(GB)[Issue 1995-11].iso
/
Aminet
/
comm
/
tcp
/
AmiTCPtxt_20.lha
/
doc
/
programmertext.txt
< prev
next >
Wrap
Text File
|
1993-08-13
|
232KB
|
6,867 lines
Chapter 3
Programmer's Manual
This chapter provides an in depth description of the AmiTCP/IP
application programming interface. Following sectionsintroduce the
socket model of communication (3.1) andthe bsdsocket.library function
calls implementing the socket abstraction. Some useful supporting
routines are described in section 3.2. The client/server model is
introduced in section 3.3. Some more advanced topics are discussed in
section 3.4. Section 3.5 summarizes the small differences between
AmiTCP/IP and 4.3BSD socket APIs. The full function reference of the
AmiTCP/IP API functions is in appendix Bstarting from page 128.
The textin sections 3.1 -- 3.4 is based on the [Leffler et al 1991a ].
3.1 Socket Concepts
The basic building block for communication is the socket. A socket is an
endpoint of communication to which a name may be bound. Each socket in
use has a type and one or more associated processes. Sockets exist
within communication domains. A communication domain is an abstraction
introduced to bundle common properties of processes communicating through
sockets. One such property is the scheme used to name sockets. Sockets
normally exchange data only with socketsin the same domain1. The
AmiTCP/IP system supports currently onlyone communication domain: the
Internet domain, which is used by processes which communicate using the
the DARPA standard communication protocols. The underlying communication
facilities provided by the domains havea significant influence on the internal
system implementation as well as the interface to socket facilities available
to a user.
3.1.1 Socket Types
Sockets are typed according to the communication properties visible to a
user. Processes are presumed to communicate only between sockets of the
same type, although there is nothing that prevents communication between
________________________________
1It may be possible to cross domain boundaries, but only if some
translation process is performed.
27
28 Section 3.1 AmiTCP/IP System Manual
sockets of different types should the underlying communication protocols
support this.
Three types of sockets currently are available to a user. A stream
socket provides for the bidirectional, reliable, sequenced, and
unduplicated flow of data without recordboundaries. Aside from the
bidirectionality of data flow, a pair ofconnected stream sockets
provides an interface nearly identical to that of pipes.2
A datagram socket supports bidirectional flow of data which is not
promised to be sequenced, reliable, or unduplicated. That is, a process
receiving messages on a datagram socketmay find messages duplicated,
and, possibly, in an order different from the order in which it was sent.
An important characteristic of a datagram socket is that record
boundaries in data are preserved. Datagram sockets closely model the
facilities found in many contemporary packet switched networks such as
the Ethernet.
A raw socket provides users access to the underlying communication
protocols which support socket abstractions. These sockets are normally
datagram oriented, though their exact characteristics are dependent on
the interface provided by the protocol. Raw sockets are not intended for
the general user; they have been provided mainly for those interested in
developing new communication protocols,or for gaining access to some of
the more esoteric facilities of an existing protocol. The use of raw
sockets is considered in section 3.4.
Another potential socket type which has interesting properties is the
reliably delivered message socket. The reliably delivered message socket
has similar properties to a datagram socket, but with reliable delivery.
There is currently no support for this type of socket, but a reliably
delivered message protocol similar to Xerox's Packet Exchange Protocol
(PEX) may be simulated at the user level. More information on this topic
can be found in section 3.4.
3.1.2 Using The Socket Library
As any other Amiga shared library the bsdsocket.library must be opened to
be able to access the functions in the library. Thiscan be done with
Exec's OpenLibrary() call. The call returns a librarybase pointer which
is task specfic, which means that each separate task (or process) must
open the library itself. This is because the AmiTCP/IPstores task
specific information to the library basestructure.
The library base pointer returned by the OpenLibrary() must be stored
in to a variable accessable from the program (usually global) named
SocketBase. Example of opening the library follows:
#include <exec/libraries.h>
...
struct Library *SocketBase = NULL;
...
if ((SocketBase = OpenLibrary("bsdsocket.library", 2)) == NULL) -
________________________________
2In the UNIX systems pipes havebeen implemented internally as simply
a pair of connected stream sockets.
System Manual AmiTCP/IP Section 3.1 29
/* couldnot open the library */
...
"
else -
/* SocketBase now points to socket base of this task */
...
"
Note thatthe library version argument of the OpenLibrary() call is
given as 2, which means that at least version 2 is needed. This is the
minimum version which should be requested, since the version 1 is
incompatible with the version 2 and up. If the application uses features
defined for some specific version (and up), a later version number should
be specified.
After theapplication is done with sockets the library must be closed.
This is done with CloseLibrary() as follows:
if (SocketBase) -
CloseLibrary(SocketBase);
SocketBase = NULL;
"
Note thatif the application in question is multithreaded, each task
(or process) need to open/close its ownlibrary base. The base opened by
the net.lib may be used by the originaltask only!
Many programs expect the error values of the socket calls to be placed
in a global variable named errno. By default a sharedlibrary cannot
know the address (nor size) of the applications variables, however.
There are two remedies to this:
1. Use function Errno() to retrieve the error value, or
2. Tell the address and the size of the errno variable to the AmiTCP/IP
by using the SetErrnoPtr() call.
The latter method requires only one additional function call to the
startup of the application, and is thusthe preferred method. The call
may look like:
#include <errno.h>
#include <sys/socket.h>
...
SetErrnoPtr(&errno, sizeof(errno));
All thisis done automatically for the application if it is linked with
the net.lib3. See section 3.1.3 for more information about the net.lib
and about compiling and linking the applications.
________________________________
3The net.lib is compiler dependent and is currently defined for SASC 6
only. The actual name of the library varies and depends on the compiler
options used.
30 Section 3.1 AmiTCP/IP System Manual
3.1.3 Compiling and Linking The Applications
AmiTCP/IP provides standard BSD Unix header files to be used by the
applications. Normally they are installed to a directory which is
assigned to a name NETINCLUDE: (see section 1.1). This means that you
should add the NETINCLUDE: to the compilers search path for include
files.
The include files are decribed briefly in the following subsection:
The NETINCLUDE Header Files
bsdsocket.h This file includes compiler specific prototypes and inline
functions for bsdsocket.library. Currently supported compilers are
GCC and SAS C version 6. The prototypes for the library functions
are automatically included by the include files when appropriate,
i.e. when the prototypes where declared in the original BSD
includes. Thus the bsdsocket.h is included by sys/socket.h, netdb.h
and arpa/inet.h.
For other compilers only C prototypes are included, so stub routines
should be used to call the functions.
errno.h Replacement for the errno.h included in the standard C-compiler
headers. This includes the file sys/errno.h, which defines symbolic
constants for the error values returned by socket library calls.
This file is BSD compatible and may well replace file provided by the
SAS/C 6.
netdb.h Contains definitions and prototypes for the network database
functions, such as the gethostbyname().
Standard BSD System Headers
sys/errno.h Error code definitions for system functions.
sys/ioctl.h Definitions for socket IO control.
sys/param.h General machine independent parameter definitions.
sys/socket.h Definitions related to sockets: types, address
families, options and prototypes.
sys/syslog.h Definations for system logging facilities.
sys/time.h Definition of structure timeval.
sys/types.h Common C type definitions and file descriptorset macros
for select().
Internet Related Headers
arpa/inet.h Inet library function prototypes (inet_addr() etc.).
Included for compatibility and only includes other include files.
netinet/in.h Protocol numbers, port conventions, inet address
definitions.
netinet/in_systm.h Some network byte order type definitions.
netinet/ip.h IP packet header, packet options, timestamp.
System Manual AmiTCP/IP Section 3.1 31
netinet/ip_icmp.h ICMP packet structure.
netinet/ip_var.h Defines IP statistics, external IP packet header,
reassemble queues structures.
netinet/tcp.h Defines the TCP packet structure.
netinet/udp.h Defines the UDP packet structure.
Network Related Headers
net/if.h Defines the interface for network adapter drivers.
net/if_arp.h General protocol independent ARP structures.
net/route.h Routing ioctl definitions.
net/sana2errno.h Sana-II related error definitions.
net/sana2tags.h Tag definitions for configuring the Sana-II software
network interface.
Inetd Support
inetd.h Internet daemon interface definitions.
inetdlib.h Internet daemon library definitions.
Prototypes
clib/socket_inlines.h Inline function definitions for those BSD
socket API functions, which are not implemented strictly like
originals by bsdsocket.library.
clib/socket_protos.h bsdsocket.library function call prototypes.
SAS/C Pragmas
pragmas/socket_pragmas.h SAS/C pragma library calls for
bsdsocket.library.
SAS/C Proto -file
proto/socket.h Include file normally included by the SAS/C programs.
Defines the socket base variable and includes the files
clib/socket_protos.h and pragmas/socket_pragmas.h.
GCC Inline Functions
inline/socket.h GCC inline functions for the bsdsocket.library
functions.
Function Description File
fd/socket_lib.fd Standard fd-file which specifies in which registers
the arguments to the bsdsocket.library functions are passed.
This file can be used to obtain information needed to call the
bsdsocket.library functions by the assembler programs.
Sana-II Header Files
devices/sana2.h Definitions for the Sana-II network device driver
interface.
32 Section 3.1 AmiTCP/IP System Manual
devices/sana2specialstats.h Special statistics definitions for the
Sana-II.
Miscellaneous
charread.h Macro package to do buffered byte-by-byte reading from a
socket.
lineread.h Definitions for buffered line orientedreading from a
socket.
Linking With net.lib
AmiTCP/IP distribution includes a link library named net.lib to be used
by the applications. It is normally located in the directory which has
an assigned name NETLIB:.
The library contains compiler dependent code which makes the library
itself compiler dependent. Currently only SASC version6 is supported4.
net.lib features automatic initialization and termination functions
which open and close the bsdsocket.library for the application. Using
this feature it is possible to compile some typical BSD Unix socket based
applications with AmiTCP/IP without anymodifications to the original
source code. Note that this base may be used by the process starting the
program, i.e. the one that executes themain(). This applies to the
included utility functions which call the socket library, too.
The library also defines new array of error names to be used by
perror() library function. This is done because the error name array
normally used by Amiga C compilers doesnot contain enough error entries,
resulting perror() to print "Unknown error code" if some socket error is
passed. Note that for perror() to work the error valuemust be placed
into the global errno variable. This is accomplished by the
SetErrnoPrt() call made in the automaticinitialization function.
For the library functions to take effect, the library must be specified
before the C compiler own libraries in the link command line.
3.1.4 Socket Creation
To create a socket the socket() system call is used:
s = socket(domain, type, protocol);
This call requests that the system create a socket in the specified
domain and of the specified type. A particular protocol may also be
requested. If the protocol is left unspecified (a value of 0), the
system will select an appropriate protocol from those protocols which
comprise the communication domain and which may be used to support the
requested socket type. The user is returned a descriptor (a small
integer number) which may be used in later system calls which operate on
sockets. The domain is specified as one of the manifest constants
________________________________
4But since the source for the library is provided, it can be used with
any C compiler.
System Manual AmiTCP/IP Section 3.1 33
defined in the file sys/socket.h. For the Internet domain the constant
is AF_INET5. The socket types are also defined in this file and one of
SOCK_STREAM, SOCK_DGRAM or SOCK_RAW mustbe specified. To create a stream socket
in the Internet domain the following call might be used:
s = socket(AF_INET, SOCK_STREAM, 0);
This call would result in a stream socket being created with the TCP
protocol providing the underlying communication support. To create a
datagram socket the call might be:
s = socket(AF_INET, SOCK_DGRAM, 0);
The default protocol (used when the protocol argument to the socket()
call is 0) should be correct for most every situation. However, it is
possible to specify a protocol other than the default; this will be
covered in section 3.4.
There areseveral reasons a socket() call may fail. Aside from the
rare occurrence of lack of memory (ENOBUFS), a socket request may fail
due to a request for an unknown protocol(EPROTONOSUPPORT), or a request
for a type of socket for which there isno supporting protocol
(EPROTOTYPE).
3.1.5 Binding Local Names
A socket is created without a name. Until a name is bound to a socket,
processes have no way to reference it and, consequently, no messages may
be received on it. Communicating processes are bound by an association.
In the Internet domain, an association is composed of local and foreign
addresses, and local and foreign ports,In most domains, associations
must be unique. In the Internet domain there may neverbe duplicate
<protocol, local address, local port, foreign address, foreign port>
tuples.
The bind() system call allows a process to specify half of an
association, <local address, local port>, while the connect() and
accept() calls are used to complete a socket's association.
In the Internet domain, binding names to sockets can be fairly complex.
Fortunately, it is usually not necessaryto specifically bind an address
and port number to a socket, because theconnect() and send() calls will
automatically bind an appropriate address if they are used with an
unbound socket.
The bind() system call is used as follows:
bind(s, name, namelen);
The bound name is a variable length bytestring which is interpreted by
the supporting protocol(s). Its interpretation may vary from
communication domain to communication domain (this is one of the
properties which comprise the domain). As mentioned, in the Internet
domain names contain an Internet addressand port number.
In binding an Internet address things are a little complicated:
________________________________
5The manifest constants are named AF _whatever as they indicate the
``address format'' to use in interpreting names.
34 Section 3.1 AmiTCP/IP System Manual
#include <sys/types.h>
#include <netinet/in.h>
...
struct sockaddr_in sin;
...
bind(s, (struct sockaddr *) &sin, sizeof (sin));
The selection of what to place in the address sin requires some
discussion. We will come back to the problem of formulating Internet
addresses in section 3.2 when the library routines used in name
resolution are discussed.
3.1.6 Connection Establishment
Connection establishment is asymmetric,with one process a ``client'' and
the other a ``server''. The server, when willing to offer its advertised
services, binds a socket to a well--known address associated with the
service and then passively ``listens'' on its socket. It is then
possible for an unrelated process to rendezvous with the server. The
client requests services from the serverby initiating a ``connection''
to the server's socket. On the client side the connect() call is used to
initiate a connection. Using the Internet domain, thismight apper as:
struct sockaddr_in server;
...
connect(s, (struct sockaddr *)&server, sizeof (server));
where server in the example above would contain Internet address and
port number of the server to which the client process wishes to speak.
If the client process's socket is unbound at the time of the connect
call, the system will automatically select and bind a name to the socket
if necessary. This is the usual way that local addresses are bound to a
socket.
An erroris returned if the connection was unsuccessful (any name
automatically bound by the system, however, remains). Otherwise, the
socket is associated with the server anddata transfer may begin. Some
of the more common errors returned whena connection attempt fails are:
ETIMEDOUT After failing to establish a connection for a period of time,
the system decided there was no point in retrying the connection
attempt any more. This usually occurs because the destination host
is down, or because problems in the network resulted in transmissions
being lost.
ECONNREFUSED The host refusedservice for some reason. This is usually
due to a server process not being present at the requested name.
ENETDOWN or EHOSTDOWN These operational errors are returned based on
status information delivered to the client host by the underlying
communication services.
ENETUNREACH or EHOSTUNREACH These operational errors can occur either
because the network or host is unknown (no route to the network or
System Manual AmiTCP/IP Section 3.1 35
host is present), or because of status information returned by
intermediate gateways or switching nodes. Many times the status
returned is not sufficient to distinguish a network being down from a
host being down, in which case the system indicates the entire
network is unreachable.
For the server to receive a client's connection it must perform two
steps after binding its socket. The first is to indicate a willingness
to listen for incoming connection requests:
listen(s, 5);
The second parameter to the listen() call specifies the maximum number of
outstanding connections which may be queued awaiting acceptance by the
server process; this number may be limited by the system. Should a
connection be requested while the queueis full, the connection will not
be refused, but rather the individual messages which comprise the request
will be ignored. This gives a harried server time to make room in its
pending connection queue while the client retries the connection request.
Had the connection been returned with the ECONNREFUSED error, the client
would be unable to tell if the server was up or not. As it is now it is
still possible to get the ETIMEDOUT error back, though this is unlikely.
The backlog figure supplied with the listen call is currently limited by the
system to a maximum of 5 pending connections on any one queue. This avoids
the problem of processes hogging systemresources by setting an infinite backlog,
then ignoring all connection requests.
With a socket marked as listening, a server may accept a connection:
struct sockaddr_in from;
...
fromlen = sizeof (from);
newsock = accept(s, (struct sockaddr *)&from, &fromlen);
A new descriptor is returned on receiptof a connection (along with a new
socket). If the server wishes to find out who its client is, it may
supply a buffer for the client socket'sname. The value--result
parameter fromlen is initialized by theserver to indicate how much space
is associated with from, then modified on return to reflect the true size
of the name. If the client's name is not of interest,the second
parameter may be a NULL pointer.
accept()normally blocks. That is, accept() will not return until a
connection is available or the system call is interrupted by a signal6 to
the process. Further, there is no way for a process toindicate it will
accept connections from only a specificindividual, or individuals. It
is up to the user process to consider who the connection is from and
close down the connection if it does notwish to speak to the process.
If the server process wants to accept connections on more than one
socket, or wants to avoid blocking on the accept call, there are
alternatives; they will be considered insection 3.4.
________________________________
6By default, the CTRL-C signalinterrupts the system calls, but the
application may change this, however.
36 Section 3.1 AmiTCP/IP System Manual
3.1.7 Data Transfer
With a connection established, data maybegin to flow. To send and
receive data there are a number of possible calls. With the peer entity
at each end of a connection anchored, auser can send or receive a
message without specifying the peer. The calls send()and recv() may be
used:
send(s, buf, sizeof (buf), flags);
recv(s, buf, sizeof (buf), flags);
While send() and recv() are virtually identical to the standard I/O
routines, the extra flags argument is important. Theflags, defined in
sys/socket.h, may be specified as a non--zero value if one or more of the
following is required:
MSG_OOB Send/receive out of band data.
MSG_PEEK Lookat data without reading.
MSG_DONTROUTESend data without routing packets.
Out of band data is a notion specific to stream sockets, and one which
we will not immediately consider. The option to have data sent without
routing applied to the outgoing packetsis currently used only by the
routing table management process, and isunlikely to be of interest to
the casual user. The ability to preview data is, however, of interest.
When MSG_PEEK is specified with a recv() call, any data present is
returned to the user, but treated as still ``unread''. That is, the next
recv() call applied to the socket will return the data previously
previewed.
3.1.8 Discarding Sockets
Once a socket is no longer of interest,it may be discarded by applying a
CloseSocket() to the descriptor,
CloseSocket(s);
If data is associated with a socket which promises reliable delivery
(e.g. a stream socket) when a close takes place, the system will
continue to attempt to transfer the data. However, after a fairly long
period of time, if the data is still undelivered, it will be discarded.
Should a user have no use for any pending data, it may perform a
shutdown() on the socket prior to closing it. This call is of the form:
shutdown(s, how);
where how is 0 if the user is no longerinterested in reading data, 1 if
no more data will be sent, or 2 if no data is to be sent or received.
System Manual AmiTCP/IP Section 3.1 37
3.1.9 Connectionless Sockets
To this point we have been concerned mostly with sockets which follow a
connection oriented model. However, there is also support for
connectionless interactions typical of the datagram facilities found in
contemporary packet switched networks. A datagram socket provides a
symmetric interface to data exchange. While processesare still likely
to be client and server, there is no requirement for connection
establishment. Instead, each message includes the destination address.
Datagramsockets are created as before. If a particular local address
is needed, the bind operation must precede the first data transmission.
Otherwise, the system will set the localaddress and/or port when data is
first sent. To send data, the sendto() call is used,
sendto(s, buf, buflen, flags, (struct sockaddr *)&to, tolen);
The s, buf, buflen, and flags parametersare used as before. The to and
tolen values are used to indicate the address of the intended recipient
of the message. When using an unreliable datagram interface, it is
unlikely that any errors will be reported to the sender. When
information is present locally to recognize a message that can not be
delivered (for instance when a network is unreachable), the call will
return -1 and the global value errno will contain an error number (See
section 3.1.2 for discussion about errno).
To receive messages on an unconnected datagram socket, the recvfrom()
call is provided:
recvfrom(s, buf, buflen, flags, (struct sockaddr *)&from, &fromlen);
Once again, the fromlen parameter is handled in a value--result fashion,
initially containing the size of the from buffer, and modified on return
to indicate the actual size of the address from which the datagram was
received.
In addition to the two calls mentioned above, datagram sockets may also
use the connect() call to associate a socket with a specific destination
address. In this case, any data sent on the socket will automatically be
addressed to the connected peer, and only data received from that peer
will be delivered to the user. Only one connected address is permitted
for each socket at one time; a second connect() will change the
destination address, and a connect() toa null address (family AF_UNSPEC)
will disconnect. Connect requests on datagram socketsreturn
immediately, as this simply results in the system recording the peer's
address (as compared to a stream socket,where a connect request
initiates establishment of an end to endconnection). accept() and listen()
are not used with datagram sockets.
While a datagram socket is connected, errors from recent send() calls
may be returned asynchronously. These errors may be reported on
subsequent operations on the socket, ora special socket option used with
getsockopt(), SO_ERROR,may be used to interrogate the error status. A
select() for reading or writing will return true when an error indication
has been received. The next operation will return theerror, and the
error status is cleared. Other of the less important details of datagram
sockets are described in section 3.4.
38 Section 3.1 AmiTCP/IP System Manual
3.1.10 Input/Output Multiplexing
One last facility often used in developing applications is the ability to
multiplex i/o requests among multiple sockets. This is done using the
select() call. The select() call provided by AmiTCP/IPis actually a
compile time inline function (or normalstub with compilers without
inline facility) which calls the WaitSelect(). The WaitSelect() call is
similar to the normal select() call, buthas one extra argument
specifying a pointer to a signal mask for the signals which should break
the selection (in addition to the timeouts and the break signal). This
makes possible to use WaitSelect() instead of normal Wait() as a driver
for the applications event loop. If the pointer is given as NULL the
functionality is as with BSD select(). The inline (orstub) function for select*
*()
actually just calls the WaitSelect() with last argument as NULL.
Here is abrief example of the usage of the WaitSelect():
#include <sys/time.h>
#include <sys/types.h>
...
fd_set readmask, writemask, exceptmask;
struct timeval timeout;
ULONG signalmask;
...
WaitSelect(nfds, &readmask, &writemask, &exceptmask, &timeout,
&signalmask);
WaitSelect() takes as arguments pointersto three sets, one for the set
of file descriptors for which the callerwishes to be able to read data
on, one for those descriptors to which data is to be written, and one for
which exceptional conditions are pending; out-of-band data is the only
exceptional condition currently implemented. If the user is not
interested in certain conditions (i.e.,read, write, or exceptions), the
corresponding argument to the select() should be a NULL pointer.
Each setis actually a structure containing an array of long integer
bit masks; the size of the array is setby the definition FD_SETSIZE. The
array is long enough to hold one bit foreach of FD_SETSIZE file
descriptors.
The macros FD_SET(fd, &mask) and FD_CLR(fd, &mask) have been provided
for adding and removing file descriptorfd in the set mask. The set
should be zeroed before use, and the macro FD_ZERO(&mask) has been
provided to clear the set mask. The parameter nfds inthe select() call
specifies the range of file descriptors(i.e. one plusthe value of the
largest descriptor) to be examined in aset.
A timeoutvalue may be specified if the selection is not to last more
than a predetermined period of time. If the fields intimeout are set to
0, the selection takes the form of a poll, returning immediately. If the
last parameter is a NULL pointer, the selection will block indefinitely7.
________________________________
7To be more specific, a returntakes place only when a descriptor is
selectable, or when a signal is receivedby the caller, interrupting the
system call.
System Manual AmiTCP/IP Section 3.1 39
The lastargument is a pointer to the mask specifying signals for which
the WaitSelect() should break. WaitSelect() normally returns the number
of file descriptors selected; if the WaitSelect() call returns due to the
timeout expiring, then the value 0 is returned. If the WaitSelect()
terminates because of an error or interruption, a -1 is returned with the
error number in errno, and with the filedescriptor masks unchanged. The
signal mask is altered on return to holdthe bits for the signals which
caused the break.
Assuminga successful return, the three sets will indicate which file
descriptors are ready to be read from, written to, or have exceptional
conditions pending. The status of a file descriptor ina select mask may
be tested with the FD_ISSET(fd, &mask) macro, which returns a non-zero
value if fd is a member of the set mask,and 0 if it is not.
To determine if there are connections waiting on a socket to be used
with an accept() call, select() can be used, followed by a
FD_ISSET(fd, &mask) macro to check for read readiness on the appropriate
socket. If FD_ISSET() returns a non-zero value, indicating permission to
read, then a connection is pending on the socket.
As an example, to read data from two sockets, s1 and s2 as it is
available from each and with a one--second timeout, the following code
might be used:
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
...
fd_set read_template;
struct timeval wait;
int nb;
int s1,s2;
int maxfd;
...
maxfd = s1 > s2 ? s1 : s2;
for (;;) -
wait.tv_sec = 1; /* onesecond */
wait.tv_usec = 0;
FD_ZERO(&read_template);
FD_SET(s1, &read_template);
FD_SET(s2, &read_template);
nb = select(maxfd, &read_template, NULL, NULL, &wait);
if (nb <=0) -
/* An error occurred during the select, or
the select timed out. */
"
if (FD_ISSET(s1, &read_template)) -
/* Socket #1 is ready to be readfrom. */
"
if (FD_ISSET(s2, &read_template)) -
/* Socket #2 is ready to be readfrom. */
40 Section 3.2 AmiTCP/IP System Manual
"
"
Note theusage of the select(), which calls WaitSelect() with NULL
signal mask pointer.
In 4.2BSD, the arguments to select() were pointers to integers instead
of pointers to fd_sets. This type ofcall will still work as long as the
number of file descriptors being examined is less than the number of bits
in an integer; however, the methods illustrated above should be used in
all current programs.
select()provides a synchronous multiplexing scheme. Asynchronous
notification of output completion, inputavailability, and exceptional
conditions is possible through use of the SigIO and SigURG signals
described in section 3.4.
3.2 Network Library Routines
The discussion in section 3.1 indicatedthe possible need to locate and
construct network addresses when using the interprocess communication
facilities in a distributed environment. To aid in this task a number of
routines have been added to the Amiga shared socket library. In this
section we will consider the routines provided to manipulate network
addresses.
Locatinga service on a remote host requires many levels of mapping
before client and server may communicate. A service is assigned a name
which is intended for human consumption;e.g. ``the login server on host
monet''. This name, and the name of the peer host, must then be
translated into network addresses whichare not necessarily suitable for
human consumption. Finally, the address must then usedin locating a
physical location and route to the service. The specifics of these three
mappings are likely to vary between network architectures. For instance,
it is desirable for a network to not require hosts to be named in such a
way that their physical location is known by the client host. Instead,
underlying services in the network may discover the actual location of the
host at the time a client host wishes tocommunicate. This ability to have
hosts named in a location independent manner may induce overhead in connection
establishment, as a discovery process must take place, but allows a host to
be physically mobile without requiring it to notify its clientele of its current
location.
Standardroutines are provided for: mapping host names to network
addresses, network names to network numbers, protocol names to protocol
numbers, and service names to port numbers and the appropriate protocol
to use in communicating with the serverprocess. The file netdb.h must
be included when using any of these routines.
3.2.1 Host Names
An Internet host name to address mappingis represented by the hostent
structure:
System Manual AmiTCP/IP Section 3.2 41
struct hostent -
char *h_name; /* official name of host */
char **h_aliases; /* alias list */
int h_addrtype; /* host address type (e.g., AF_INET) */
int h_length; /* length of address */
char **h_addr_list; /* list of addresses, nullterminated */
";
#define h_addr h_addr_list[0] /* first address, network byte order */
The routine gethostbyname() takes an Internet host name and returns a
hostent structure, while the routine gethostbyaddr() maps Internet host
addresses into a hostent structure.
The official name of the host and its public aliases are returned by
these routines, along with the address type (family) and a null
terminated list of variable length addresses. This list of addresses is
required because it is possible for a host to have many addresses, all
having the same name. The h_addr definition is provided for backward
compatibility, and is defined to be thefirst address in the list of
addresses in the hostent structure.
The database for these calls is provided either by the configuration
file or by use of a name server. Because of the differences in these
databases and their access protocols, the information returned may
differ. When using the host table version of gethostbyname(), only one
address will be returned, but all listedaliases will be included. The
name server version may return alternateaddresses, but will not provide
any aliases other than one given as argument.
3.2.2 Network Names
As for host names, routines for mappingnetwork names to numbers, and
back, are provided. These routines return a netent structure:
/*
* Assumption here is that a network number
* fits in 32 bits -- probably a poor one.
*/
struct netent -
char *n_name; /* official name of net */
char **n_aliases; /* alias list */
int n_addrtype; /* net address type */
int n_net; /* networknumber, host byte order */
";
The routines getnetbyname(), andgetnetbynumber() are the network
counterparts to the host routines described above. The routines uses
data read from AmiTCP/IP configuration file.
3.2.3 Protocol Names
For protocols, the protoent structure defines the protocol--name mapping
used with the routines getprotobyname()and getprotobynumber():
42 Section 3.2 AmiTCP/IP System Manual
struct protoent -
char *p_name; /* official protocol name */
char **p_aliases; /* alias list */
int p_proto; /* protocol number */
";
3.2.4 Service Names
Information regarding services is a bitmore complicated. A service is
expected to reside at a specific ``port'' and employ a particular
communication protocol. This view is consistent with the Internet
domain, but inconsistent with other network architectures. Further, a
service may reside on multiple ports. If this occurs,the higher level
library routines will have to be bypassed or extended. A service mapping
is described by the servent structure:
struct servent -
char *s_name; /* official service name */
char **s_aliases; /* alias list */
int s_port; /*port number, network byte order */
char *s_proto; /* protocol to use */
";
The routine getservbyname() maps service names to a servent structure
by specifying a service name and, optionally, a qualifying protocol.
Thus the call
sp = getservbyname("telnet", NULL);
returns the service specification for atelnet server using any protocol,
while the call
sp = getservbyname("telnet", "tcp");
returns only that telnet server which uses the TCP protocol. The routine
getservbyport() is also provided. The getservbyport()routine has an
interface similar to that provided by getservbyname(); an optional
protocol name may be specified to qualify lookups.
3.2.5 Miscellaneous
With the support routines described above, an Internet application
program should rarely have to deal directly with addresses. This allows
services to be developed as much as possible in a network independent
fashion. It is clear, however, that purging all network dependencies is
very difficult. So long as the user is required to supply network
addresses when naming services and sockets there will always some network
dependency in a program. For example, the normal codeincluded in client
programs, such as the remote login program, is as follows:
System Manual AmiTCP/IP Section 3.2 43
Remote Login Client Code
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <netdb.h>
...
int main(int argc, char *argv[])
-
struct sockaddr_in server;
struct servent *sp;
struct hostent *hp;
int s;
...
sp = getservbyname("login","tcp");
if (sp == NULL) -
fprintf(stderr, "rlogin: tcp/login: unknown service"n");
exit(1);
"
hp = gethostbyname(argv[1]);
if (hp == NULL) -
fprintf(stderr, "rlogin: %s: unknown host"n",argv[1]);
exit(2);
"
bzero((char *)&server, sizeof (server));
server.sin_port = sp->s_port;
bcopy(hp->h_addr, (char *)&server.sin_addr, hp->h_length);
server.sin_family = hp->h_addrtype;
s = socket(AF_INET, SOCK_STREAM, 0);
if (s < 0) -
perror("rlogin: socket");
exit(3);
"
...
/* Connect does the bind()for us */
if (connect(s, (struct sockaddr *)&server, sizeof (server)) < 0) -
perror("rlogin: connect");
exit(5);
"
...
"
(This example will be considered in more detail in section 3.3.)
If we wanted to make the remote login program independent of the
Internet protocols and addressing schemewe would be forced to add a
layer of routines which masked the network dependent aspects from the
mainstream login code. For the current facilities available in the
system this does not appear to be worthwhile.
Aside from the address-related data base routines, there are several
other routines available in the run-timelibrary which are of interest to
44 Section 3.3 AmiTCP/IP System Manual
users. These are intended mostly to simplify manipulation of names and
addresses. The routines for manipulating variable length byte strings
and handling byte swapping of network addresses and values are summarized
below:8.
bcmp(s1, s2, n)
Compare byte-strings; 0 if same, not 0 otherwise.
bcopy(s1, s2, n)
Copy n bytes from s1 to s2.
bzero(base, n)
Zero-fill n bytes starting at base.
htonl(val)
Convert 32-bit quantity from host to network byte order.
htons(val)
Convert 16-bit quantity from host to network byte order.
ntohl(val)
Convert 32-bit quantity from network to host byte order.
ntohs(val)
Convert 16-bit quantity from network to host byte order.
The byteswapping routines are provided because the operating system
expects addresses to be supplied in network order. Onsome
architectures, such as the VAX, host byte ordering is different than
network byte ordering. Consequently, programs are sometimes required to
byte swap quantities. The library routines which return network
addresses provide them in network orderso that they may simply be copied
into the structures provided to the system. This implies users should
encounter the byte swapping problem onlywhen interpreting network
addresses. For example, if an Internet port is to be printed out the
following code would be required:
printf("port number %d"n", ntohs(sp->s_port));
On machines where unneeded (as on Amiga)these routines are defined as
null macros.
3.3 Client/Server Model
The most commonly used paradigm in constructing distributed applications
is the client/server model. In this scheme client applications request
services from a server process. This implies an asymmetry in
establishing communication between the client and server which has been
________________________________
8The byte string functions areprovided by the C-compiler. The byte
order functions are provided as preprocessor macros.
System Manual AmiTCP/IP Section 3.3 45
examined in section 3.1. In this section we will lookmore closely at
the interactions between client and server, and consider some of the
problems in developing client and serverapplications.
The client and server require a well known set of conventions before
service may be rendered (and accepted). This set of conventions
comprises a protocol which must be implemented at both ends of a
connection. Depending on the situation, the protocol may be symmetric or
asymmetric. In a symmetric protocol, either side may play the master or
slave roles. In an asymmetric protocol, one side is immutably recognized
as the master, with the other as the slave. An example of a symmetric
protocol is the TELNET protocol used inthe Internet for remote terminal
emulation. An example of an asymmetric protocol is theInternet file
transfer protocol, FTP. No matter whether the specific protocol used in
obtaining a service is symmetric or asymmetric, when accessing a service there
is a ``client process'' and a ``server process''. Wewill first consider the
properties of server processes, then client processes.
A serverprocess normally listens at a well known address for service
requests. That is, the server process remains dormantuntil a connection
is requested by a client's connection tothe server's address. At such a
time the server process ``wakes up'' andservices the client, performing
whatever appropriate actions the clientrequests of it.
Alternative schemes which use a service server may be used to eliminate
a flock of server processes clogging thesystem while remaining dormant
most of the time. For Internet servers in 4.3BSD, thisscheme has been
implemented via inetd, the so called ``internet super-server.'' Inetd
listens at a variety of ports, determined at start-up by reading a
configuration file. When a connection is requested toa port on which
inetd is listening, inetd executes the appropriate server program to
handle the client. Inetd will be described in more detail in section
3.4.
3.3.1 Servers
In 4.3BSD most servers are accessed at well known Internet addresses or
UNIX domain names. For example, the remote login server's main loop is
of the form shown below (AmiTCP/IP way):
main(int argc, char *argv)
-
int f;
struct sockaddr_in from;
struct servent *sp;
sp = getservbyname("login", "tcp");
if (sp ==NULL) -
fprintf(stderr, "rlogind: tcp/login: unknown service"n");
exit(1);
"
...
sin.sin_port = sp->s_port; /* Restricted port */
...
46 Section 3.3 AmiTCP/IP System Manual
f = socket(AF_INET, SOCK_STREAM, 0);
...
if (bind(f, (struct sockaddr *) &sin, sizeof (sin)) < 0) -
...
"
...
listen(f, 5);
for (;;)-
int g, len = sizeof (from);
g = accept(f, (struct sockaddr *)&from, &len);
if (g < 0) -
if (errno != EINTR)
syslog(LOG_ERR, "rlogind: accept: %s", errors[errno]);
continue;
"
/*
* AmiTCP code follows...
*/
id = ReleaseSocket(g, UNIQUE_ID);
startit(id, &from);
"
"
The firststep taken by the server is look up its service definition:
sp = getservbyname("login", "tcp");
if (sp == NULL) -
fprintf(stderr, "rlogind: tcp/login: unknown service"n");
exit(1);
"
The result of the getservbyname call isused in later portions of the
code to define the Internet port at which it listens for service requests
(indicated by a connection).
Once a server has established a pristine environment, it creates a
socket and begins accepting service requests. The bind() call is
required to insure the server listens atits expected location.
The mainbody of the loop is fairly simple:
for (;;) -
int g, len = sizeof (from);
g = accept(f, (struct sockaddr *)&from, &len);
if (g < 0) -
if (errno != EINTR)
syslog(LOG_ERR, "rlogind: accept: %s", errors[errno]);
continue;
"
/*
* AmiTCP code follows...
*/
id = ReleaseSocket(g, UNIQUE_ID);
startit(id, &from);
"
System Manual AmiTCP/IP Section 3.3 47
An accept() call blocks the server until a client requests service.
This call could return a failure statusif the call is interrupted by a
signal such as CTRL-C (to be discussed in section 3.4). Therefore, the
return value from accept() is checked toinsure a connection has actually
been established.
With a connection in hand, servers using AmiTCP/IP socket library,
this new socket is released to an external list inside AmiTCP/IP process
via ReleaseSocket() call. ReleaseSocket() returns an id (unique if
requested). startit() starts a new AmigaOS task and informs the id for
it. This new task then uses ObtainSocket() with id asargument to
receive the socket. The address of the client is alsohandled the new
task because it requires it in authenticating clients.
3.3.2 Clients
The client side of the remote login service was shown earlier in section
3.2. One can see the separate, asymmetric roles of theclient and server
clearly in the code. The server is a passive entity, listening for
client connections, while the client process is an active entity,
initiating a connection when invoked.
Let us consider more closely the steps taken by the client remote login
process. As in the server process, the first step is to locate the
service definition for a remote login:
sp = getservbyname("login", "tcp");
if (sp == NULL) -
fprintf(stderr, "rlogin: tcp/login: unknown service"n");
exit(1);
"
Next thedestination host is looked up with a gethostbyname() call:
hp = gethostbyname(argv[1]);
if (hp == NULL) -
fprintf(stderr, "rlogin: %s: unknown host"n", argv[1]);
exit(2);
"
With this accomplished, all that is required is to establish a connection
to the server at the requested host andstart up the remote login
protocol. The address buffer is filled in with the Internet address and
rlogin port number of the foreign host.
bzero((char *)&server, sizeof (server));
server.sin_port = sp->s_port;
bcopy(hp->h_addr, (char *) &server.sin_addr, hp->h_length);
server.sin_family = hp->h_addrtype;
A socket is created, and a connection initiated. Notethat connect()
implicitly performs a bind() call, because s is unbound.
s = socket(hp->h_addrtype, SOCK_STREAM, 0);
if (s < 0) -
48 Section 3.3 AmiTCP/IP System Manual
perror("rlogin: socket");
exit(3);
"
...
if (connect(s, (struct sockaddr *) &server,
sizeof (server)) < 0) -
perror("rlogin: connect");
exit(4);
"
The details of the remote login protocolwill not be considered here.
3.3.3 Connectionless Servers
While connection-based services are thenorm, some services are based on
the use of datagram sockets. One, in particular, is the ``rwho'' service
which provides users with status information for hosts connected to a
local area network. This service, while predicated onthe ability to
broadcast information to all hosts connected to a particular network, is
of interest as an example usage of datagram sockets.
A user onany machine running the rwho server may find out the current
status of a machine with the ruptime program. The output generated is
illustrated below.
Ruptime Output
arpa up 9:45, 5 users, load 1.15, 1.39, 1.31
cad up 2+12:04, 8 users, load 4.67, 5.13, 4.59
calder up 10:10, 0 users,load 0.27, 0.15, 0.14
dali up 2+06:28, 9 users, load 1.04, 1.20, 1.65
degas up 25+09:48, 0 users, load 1.49, 1.43, 1.41
ear up 5+00:05, 0 users, load 1.51, 1.54, 1.56
ernie down 0:24
esvax down 17:04
ingres down 0:26
kim up 3+09:16, 8 users, load 2.03, 2.46, 3.11
matisse up 3+06:18, 0 users, load 0.03, 0.03, 0.05
medea up 3+09:39, 2 users,load 0.35, 0.37, 0.50
merlin down 19+15:37
miro up 1+07:20, 7 users, load 4.59, 3.28, 2.12
monet up 1+00:43, 2 users,load 0.22, 0.09, 0.07
oz down 16:09
statvax up 2+15:57, 3 users, load 1.52, 1.81, 1.86
ucbvax up 9:34, 2 users, load 6.08, 5.16, 3.28
Status information for each host is periodically broadcast by rwho
server processes on each machine. The same server process also receives
the status information and uses it to update a database. This database
is then interpreted to generate the status information for each host.
Servers operate autonomously, coupled only by the local network and its
broadcast capabilities.
Note thatthe use of broadcast for such a task is fairly inefficient,
as all hosts must process each message,whether or not using an rwho
System Manual AmiTCP/IP Section 3.3 49
server. Unless such a service is sufficiently universal and is
frequently used, the expense of periodicbroadcasts outweighs the
simplicity.
The rwhoserver, in a simplified form, is pictured next9:
BYTE alrmsig;
main()
-
long on;
fd_set readfds;
...
sp = getservbyname("who", "udp");
sin.sin_port = sp->s_port;
net = getnetbyname("localnet");
sin.sin_addr = inet_makeaddr(INADDR_ANY, net);
...
s = socket(AF_INET, SOCK_DGRAM, 0);
...
on = 1;
if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) -
syslog(LOG_ERR, "rwhod: setsockopt SO_BROADCAST: %s",
strerror(errno));
exit(1);
"
bind(s, (struct sockaddr *) &sin, sizeof (sin));
...
alrmsig =AllocSignal(-1);
onalrm();/* activate and handle periodic alarm system */
FD_ZERO(&readfds);
FD_SET(s, &readfds);
for (;;)-
struct whod wd;
struct sockaddr_in from;
int n, cc, whod, len = sizeof (from);
ULONG alrmmask;
alrmmask = 1 << alrmsig;
n = WaitSelect(s, &readfds, NULL,NULL, NULL, &alrmmask);
if (n < 0) -
syslog(LOG_ERR, "rwhod: WaitSelect: %s", strerror(errno));
exit(1);
"
if (alrmmask)
onalrm(); /* handles the alarm */
if (n > 0) -
cc = recvfrom(s, (char *)&wd, sizeof (wd), 0,
(struct sockaddr *)&from, &len);
if (cc <= 0) -
________________________________
9A real code must always test the return values of various services
against errors. Thes e tests are partly omitted from this code to show
the matters important to this section.
50 Section 3.3 AmiTCP/IP System Manual
if (cc < 0)
syslog(LOG_ERR, "rwhod: recv: %s", strerror(errno));
continue;
"
if (from.sin_port != sin.sin_port) -
syslog(LOG_ERR, "rwhod: %ld: bad from port",
ntohs(from.sin_port));
continue;
"
...
if (!verify(wd.wd_hostname)) -
syslog(LOG_ERR, "rwhod: malformed host name from %lx",
ntohl(from.sin_addr.s_addr));
continue;
"
(void) sprintf(path, "%s/whod.%s", RWHODIR, wd.wd_hostname);
whod = open(path, O_WRONLY _ O_CREAT _ O_TRUNC, 0666);
...
(void) time(&wd.wd_recvtime);
(void) write(whod, (char *)&wd, cc);
(void) close(whod);
"
"
"
There aretwo separate tasks performed by the server. The first task
is to act as a receiver of status information broadcast by other hosts on
the network. This job is carried out in the main loopof the program.
Packets received at the rwho port are interrogated to insure they've been
sent by another rwho server process, then are time stamped with their
arrival time and used to update a file indicating the status of the host.
When a host has not been heard from foran extended period of time, the
database interpretation routines assumethe host is down and indicate
such on the status reports. This algorithm is prone toerror as a server
may be down while a host is actually up,but serves our current needs.
The second task performed by the server is to supply information
regarding the status of its host. This involves periodically acquiring
system status information, packaging itup in a message and broadcasting
it on the local network for other rwho servers to hear. The supply
function is triggered by a timer and runs off a signal. Locating the
system status information is somewhat involved, but uninteresting.
Deciding where to transmit the resultantpacket is somewhat
problematical, however.
Status information must be broadcast on the local network. For
networks which do not support the notionof broadcast another scheme must
be used to simulate or replace broadcasting. One possibility is to
enumerate the known neighbors (based onthe status messages received from
other rwho servers). This, unfortunately, requires some bootstrapping
information, for a server will have no idea what machines are its
neighbors until it receives status messages from them. Therefore, if all
machines on a net are freshly booted, nomachine will have any known
neighbors and thus never receive, or send, any status information. This
is the identical problem faced by the routing table management process in
System Manual AmiTCP/IP Section 3.4 51
propagating routing status information. The standard solution, unsatisfactory
as it may be, is to inform one or more servers of known neighbors and request
that theyalways communicate with these neighbors. Ifeach server has at least
one neighbor supplied to it, status information may then propagate through
a neighbor to hosts which are not (possibly) directly neighbors. If the server
is able to support networks which provide a broadcast capability, as well as
those which do not, then networks with an arbitrary topology may share status
information10
It is important that software operating in a distributed environment
not have any site-dependent informationcompiled into it. This would
require a separate copy of the server ateach host and make maintenance a
severe headache. 4.3BSD attempts to isolate host-specific information
from applications by providing system calls which return the necessary
information11. A mechanism exists, in the form of an IoctlSocket() call,
for finding the collection of networks to which a host is directly
connected. Further, a local network broadcasting mechanism has been
implemented at the socket level. Combining these two features allows a
process to broadcast on any directly connected local network which
supports the notion of broadcasting in asite independent manner. This allows
4.3BSD to solve the problem of decidinghow to propagate status information
in the case of rwho, or more generally in broadcasting: Such status information
is broadcast to connected networks at the socket level, where the connected
networks have been obtained via the appropriate ioctl calls. The specifics
of such broadcastings are complex, however, and will be covered in section
3.4.
3.4 Advanced Topics
A number of facilities have yet to be discussed. Formost users of the
AmiTCP/IP the mechanisms already described will suffice in constructing
distributed applications. However, others will find the need to utilize
some of the features which we consider in this section.
3.4.1 OutOf Band Data
The stream socket abstraction includes the notion of ``out of band''
data. Out of band data is a logically independent transmission channel
associated with each pair of connected stream sockets. Out of band data
is delivered to the user independently of normal data. The abstraction
defines that the out of band data facilities must support the reliable
delivery of at least one out of band message at a time. This message may
contain at least one byte of data, and at least one message may be
pending delivery to the user at any onetime. For communications
protocols which support only in-band signaling (i.e. the urgent data is
________________________________
10One must, however, be concerned about loops. That is, if a host is
connected to multiple networks, it willreceive status information from
itself. This can lead to an endless, wasteful, exchange of information.
11An example of such a system call is the gethostname() call which returns
the host's official name.
52 Section 3.4 AmiTCP/IP System Manual
delivered in sequence with the normal data), the system normally extracts
the data from the normal data stream andstores it separately. This allows
users to choose between receiving the urgent data in order and receiving it
out of sequence without having to bufferall the intervening data. It is possib*
*le
to ``peek'' (via MSG_PEEK) at out of band data. If the socket has an owner,
a signal is generated when the protocolis notified of its existence. A process
can set the task to be informed by a signal via the appropriate IoctlSocket()
and SetSocketSignals() calls, as described below in section 3.4.3. If multiple
sockets may have out of band data awaiting delivery, a select() call for except*
*ional
conditions may be used to determine those sockets with such data pending. Neit*
*her
the signal nor the select() indicate theactual arrival of the out-of-band
data, but only notification that it is pending.
In addition to the information passed, a logical mark is placed in the
data stream to indicate the point at which the out of band data was
sent12. The remote login and remote shell applications use this facility
to propagate signals between client andserver processes. When a signal
flushs any pending output from the remote process(es), all data up to the
mark in the data stream is discarded.
To send an out of band message the MSG_OOB flag is supplied to a send()
or sendto() calls, while to receive outof band data MSG_OOB should be
indicated when performing a recvfrom() or recv() call. To find out if
the read pointer is currently pointing at the mark in the data stream,
the SIOCATMARK ioctl is provided:
IoctlSocket(s, SIOCATMARK, &yes);
If yes is a 1 on return, the next read will return data after the mark.
Otherwise (assuming out of band data hasarrived), the next read will
provide data sent by the client prior totransmission of the out of band
signal. The routine used in the remote login process to flush output on
receipt of an interrupt or quit signal is shown below:
#include <sys/ioctl.h>
#include <sys/socket.h>
...
oob()
-
int mark;
char waste[BUFSIZ];
/* flushterminal I/O on receipt of out of band data */
for (;;)-
if (IoctlSocket(rem, SIOCATMARK,&mark) < 0) -
perror("IoctlSocket");
break;
"
if (mark)
break;
recv(rem, waste, sizeof (waste),0);
________________________________
12AmiTCP/IP follows the BSD interpretation of the RFC 793 in which the
concept of out-of-band data is introduced. The BSD interpretation is in
conflict with (later) defined Host Requirements laid down in RFC 1122.
System Manual AmiTCP/IP Section 3.4 53
"
if (recv(rem, &mark, 1, MSG_OOB) < 0) -
perror("recv");
...
"
...
"
The normal data up to the mark if first read (discarding it), then the
out-of-band byte is read.
A processmay also read or peek at the out-of-band data without first
reading up to the mark. This is more difficult when the underlying
protocol delivers the urgent data in-band with the normal data, and only
sends notification of its presence aheadof time (e.g., the TCP protocol
used to implement streams in the Internet domain). With such protocols,
the out-of-band byte may not yet have arrived when a recv() is done with
the MSG_OOB flag. In that case, the call will return an error of
EWOULDBLOCK. Worse, there may be enoughin-band data in the input buffer
that normal flow control prevents the peer from sending the urgent data
until the buffer is cleared. The process must then read enough of the
queued data that the urgent data may bedelivered.
Certain programs that use multiple bytes of urgent data and must handle
multiple urgent signals (e.g., telnet) need to retain the position of
urgent data within the stream. This treatment is available as a
socket-level option, SO_OOBINLINE; see function reference for
setsockopt() for usage. With this option, the positionof urgent data
(the ``mark'') is retained, but the urgent data immediately follows the
mark within the normal data stream returned without the MSG_OOB flag.
Reception of multiple urgent indicationscauses the mark to move, but no
out-of-band data are lost.
3.4.2 Non-Blocking Sockets
It is occasionally convenient to make use of sockets which do not block;
that is, I/O requests which cannot complete immediately and would
therefore cause the process to be suspended awaiting completion are not
executed, and an error code is returned. Once a sockethas been created
via the socket() call, it may be markedas non-blocking by IoctlSocket()
as follows:
#include <sys/ioctl.h>
...
int s;
long yes = TRUE;
...
s = socket(AF_INET, SOCK_STREAM, 0);
...
if (IoctlSocket(s, FIONBIO, &yes) < 0)
perror("IoctlSocket FIONBIO");
exit(1);
"
...
When performing non-blocking I/O on sockets, one must be careful to
check for the error EWOULDBLOCK (storedin the global variable errno),
54 Section 3.4 AmiTCP/IP System Manual
which occurs when an operation would normally block, but the socket it
was performed on is marked as non-blocking. In particular, accept(),
connect(), send(), sendto(), recv() andrecvto() can all return
EWOULDBLOCK, and processes should be prepared to deal with such return
codes. If an operation such as a send() cannot be donein its entirety,
but partial writes are sensible (for example, when using a stream
socket), the data that can be sent immediately will be processed, and the
return value will indicate the amount actually sent.
3.4.3 Signal Driven Socket I/O
The AmiTCP/IP allows a task to be notified via a signal when a socket
has either normal or out-of-band data waiting to be read. Use of this
facility requres four steps:
1. The signals to be used must be allocated with Exec AllocSignal()
call.
2. The allocated signal(s) must be registered to the AmiTCP/IP with the
SetSocketSignals() call. The signals registered with
SetSocketSignals() affect all sockets of the calling task, so this is
usually done only after OpenLibrary() call.
3. The owner of the socket must be set to the task itself (note that the
owner of a socket is unspecified by default). This is accomplished
by the use of an IoctlSocket() call.
4. Asynchronous notification for the socket must be enabled with another
IoctlSocket() call
Note that it is application's responsibility to react on received
signals.
Sample code to allow a given process to receive information on pending
I/O requests as they occur for a sockets is given below:
#include <exec/tasks.h>
#include <sys/ioctl.h>
...
BYTE SIGIO = -1, SIGURG = -1;
...
struct Task *thisTask = FindTask(NULL); /* our task pointer */
long yes = TRUE;
/* Allocate signals for asynchronous notification */
if ((SIGIO = AllocSignal(-1)) == -1) -
fprintf(stderr, "allocSignal failed."n");
exit(1);
"
atexit(freeSignals); /* free allocated signals on exit */
if ((SIGURG = AllocSignal(-1)) == -1) -
fprintf(stderr, "allocSignal failed."n");
exit(1);
"
System Manual AmiTCP/IP Section 3.4 55
/* Set socket signals for this task */
SetSocketSignals(SIGBREAKF_CTRL_C, 1 << SIGIO, 1 << SIGURG);
/* Set the process receiving SIGIO/SIGURG signals to us */
if (IoctlSocket(s, FIOSETOWN, &thisTask) < 0) -
perror("IoctlSocket FIOSETOWN");
exit(1);
"
/* Allow receipt of asynchronous I/O signals */
if (IoctlSocket(s, FIOASYNC, &yes) < 0) -
perror("IoctlSocket FIOASYNC");
exit(1);
"
3.4.4 Selecting Specific Protocols
If the third argument to the socket() call is 0, socket will select a
default protocol to use with the returned socket of the type requested.
The default protocol is usually correct,and alternate choices are not
usually available. However, when using ``raw'' socketsto communicate
directly with lower-level protocols or hardware interfaces, the protocol
argument may be important for setting updemultiplexing. For example,
raw sockets in the Internet family may be used to implement a new
protocol above IP, and the socket will receive packets only for the
protocol specified. To obtain a particular protocol one determines the
protocol number as defined within the communication domain. For the
Internet domain one may use one of the library routines discussed in section
3.2, such as getprotobyname():
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
...
pp = getprotobyname("newtcp");
s = socket(AF_INET, SOCK_STREAM, pp->p_proto);
This would result in a socket s using astream based connection, but with
protocol type of ``newtcp'' instead of the default ``tcp.''
3.4.5 Address Binding
As was mentioned in section 3.1, bindingaddresses to sockets in the
Internet domains can be fairly complex. As a brief reminder, these
associations are composed of local and foreign addresses, and local and
foreign ports. Port numbers are allocated out of separate spaces, one
for each system and one for each domainon that system. Through the
bind() call, a process may specify halfof an association, the <local
address, local port> part, while the connect() and accept() calls are
56 Section 3.4 AmiTCP/IP System Manual
used to complete a socket's associationby specifying the <foreign
address, foreign port> part. Since the association iscreated in two
steps the association uniqueness requirement indicated previously could
be violated unless care is taken. Further, it is unrealistic to expect user
programs to always know proper values touse for the local address and local
port since a host may reside on multiplenetworks and the set of allocated
port numbers is not directly accessibleto a user.
To simplify local address binding in the Internet domain the notion of
a ``wildcard'' address has been provided. When an address is specified
as INADDR_ANY (a manifest constant defined in file netinet/in.h), the
system interprets the address as ``any valid address''. For example, to
bind a specific port number to a socket,but leave the local address
unspecified, the following code might beused:
#include <sys/types.h>
#include <netinet/in.h>
...
struct sockaddr_in sin;
...
s = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(INADDR_ANY);
sin.sin_port = htons(MYPORT);
bzero(sin.sin_zero, sizeof(sin.sin_zero));
bind(s, (struct sockaddr *) &sin, sizeof (sin));
Sockets with wildcarded local addressesmay receive messages directed to
the specified port number, and sent to any of the possible addresses
assigned to a host. For example, if a host has addresses 128.32.0.4 and
10.0.0.78, and a socket is bound as above, the process will be able to
accept connection requests which are addressed to 128.32.0.4 or
10.0.0.78. If a server process wished to only allow hosts on a given
network connect to it, it would bind theaddress of the host on the
appropriate network.
In a similar fashion, a local port may be left unspecified (specified
as zero), in which case the system willselect an appropriate port number
for it. For example, to bind a specific local addressto a socket, but
to leave the local port number unspecified:
hp = gethostbyname(hostname);
if (hp == NULL) -
...
"
bzero(&sin, sizeof(sin));
bcopy(hp->h_addr, (char *) sin.sin_addr, hp->h_length);
sin.sin_port = htons(0);
bind(s, (struct sockaddr *) &sin, sizeof (sin));
The system selects the local port numberbased on two criteria. The
first is that on 4BSD systems, Internetports below IPPORT_RESERVED
(1024) are reserved for privileged processes13 ; Internet ports above
________________________________
13All processes in AmigaOS are considered as privileged.
System Manual AmiTCP/IP Section 3.4 57
IPPORT_USERRESERVED (5000) are reserved for non-privileged servers. The
second is that the port number is not currently bound to some other
socket. In order to find a free Internet port number in the privileged
range the rresvport() library routine may be used as follows to return a
stream socket in with a privileged portnumber:
int lport = IPPORT_RESERVED - 1;
int s;
s = rresvport(&lport);
if (s < 0) -
if (errno== EAGAIN)
fprintf(stderr, "socket: all ports in use"n");
else
perror("rresvport: socket");
...
"
The restriction on allocating ports wasdone to allow processes executing
in a secure environment to perform authentication based on the
originating address and port number. For example, therlogin command
allows users to log in across a networkwithout being asked for a
password, if two conditions hold: First, the name of the system the user
is logging in from is in the file AmiTCP:db/hosts.equiv14 on the system
he is logging into (or the system name and the user name are in the
user's .rhosts file in the user's home directory), and second, that the
user's rlogin process is coming from a privileged port on the machine
from which he is logging. The port number and networkaddress of the
machine from which the user is logging in can be determined either by the from
result of the accept() call, or from thegetpeername() call.
In certain cases the algorithm used by the system in selecting port
numbers is unsuitable for an application. This is because associations
are created in a two step process. For example, the Internet file
transfer protocol, FTP, specifies that data connections must always
originate from the same local port. However, duplicateassociations are
avoided by connecting to different foreign ports. Inthis situation the
system would disallow binding the same local address and port number to a
socket if a previous data connection's socket still existed. To override
the default port selection algorithm, anoption call must be performed
prior to address binding:
...
long on = 1;
...
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
bind(s, (struct sockaddr *) &sin, sizeof (sin));
With the above call, local addresses maybe bound which are already in
use. This does not violate the uniqueness requirementas the system
still checks at connect time to be sureany other sockets with the same
local address and port do not have the same foreign address and port. If
the association already exists, the error EADDRINUSE is returned.
________________________________
14In UNIX /etc/hosts.equiv
58 Section 3.4 AmiTCP/IP System Manual
3.4.6 Broadcasting And Determining Network Configuration
By using a datagram socket, it is possible to send broadcast packets on
many networks supported by the system. The network itself must support
broadcast; the system provides no simulation of broadcast in software.
Broadcast messages can place a high loadon a network since they force
every host on the network to service them. Consequently, the ability to
send broadcast packets has been limitedto sockets which are explicitly
marked as allowing broadcasting. Broadcast is typically used for one of
two reasons: it is desired to find a resource on a local network without
prior knowledge of its address, or important functions such as routing
require that information be sent to allaccessible neighbors.
To send abroadcast message, a datagram socket should be created:
s = socket(AF_INET, SOCK_DGRAM, 0);
The socket is marked as allowing broadcasting,
long on = 1;
setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on));
and at least a port number should be bound to the socket:
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(INADDR_ANY);
sin.sin_port = htons(MYPORT);
bzero(sin.sin_zero, sizeof(sin.sin_zero));
bind(s, (struct sockaddr *) &sin, sizeof (sin));
The destination address of the message to be broadcast depends on the
network(s) on which the message is to bebroadcast. The Internet domain
supports a shorthand notation for broadcast on the local network, the
address INADDR_BROADCAST (defined in netinet/in.h). To determine the
list of addresses for all reachable neighbors requires knowledge of the
networks to which the host is connected. Since this information should
be obtained in a host independent fashion and may be impossible to
derive, 4.3BSD provides a method of retrieving this information from the
system data structures. The SIOCGIFCONF IoctlSocket()call returns the
interface configuration of a host in theform of a single ifconf
structure; this structure contains a ``data area'' which is made up of an array
of of ifreq structures, one for each network interface to which the host is
connected. These structures are defined in net/if.h asfollows:
struct ifconf -
int ifc_len; /* size of associated buffer */
union -
caddr_t ifcu_buf;
struct ifreq *ifcu_req;
" ifc_ifcu;
";
#define ifc_buf ifc_ifcu.ifcu_buf/* buffer address */
#define ifc_req ifc_ifcu.ifcu_req/* array of structures returned */
#define IFNAMSIZ 64
System Manual AmiTCP/IP Section 3.4 59
struct ifreq -
char ifr_name[IFNAMSIZ]; /*if name, e.g. "en0" */
union -
struct sockaddr ifru_addr;
struct sockaddr ifru_dstaddr;
struct sockaddr ifru_broadaddr;
short ifru_flags;
caddr_t ifru_data;
" ifr_ifru;
";
#define ifr_addr ifr_ifru.ifru_addr /* address */
#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */
#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
#define ifr_flags ifr_ifru.ifru_flags /* flags */
#define ifr_data ifr_ifru.ifru_data /* for use by interface */
The actual call which obtains the interface configuration is
struct ifconf ifc;
char buf[BUFSIZ];
ifc.ifc_len = sizeof (buf);
ifc.ifc_buf = buf;
if (IoctlSocket(s, SIOCGIFCONF, (char *) &ifc) < 0) -
...
"
After this call buf will contain one ifreq structure for each network to
which the host is connected, and ifc.ifc_len will have been modified to
reflect the number of bytes used by theifreq structures.
For eachstructure there exists a set of ``interface flags'' which tell
whether the network corresponding to that interface is up or down, point
to point or broadcast, etc. The SIOCGIFFLAGS IoctlSocket() retrieves
these flags for an interface specified by an ifreq structure as follows:
struct ifreq *ifr;
ifr = ifc.ifc_req;
for (n = ifc.ifc_len / sizeof (struct ifreq); --n >= 0; ifr++) -
/*
* We must be careful that we don't use an interface
* devoted to anaddress family other than those intended;
* if we were interested in NS interfaces, the
* AF_INET wouldbe AF_NS.
*/
if (ifr->ifr_addr.sa_family != AF_INET)
continue;
if (IoctlSocket(s, SIOCGIFFLAGS, (char *) ifr) < 0) -
...
"
/*
60 Section 3.4 AmiTCP/IP System Manual
* Skip boring cases.
*/
if ((ifr->ifr_flags & IFF_UP) == 0 __
(ifr->ifr_flags & IFF_LOOPBACK) __
(ifr->ifr_flags & (IFF_BROADCAST_ IFF_POINTTOPOINT)) == 0)
continue;
Once the flags have been obtained, the broadcast address must be
obtained. In the case of broadcast networks this is done via the
SIOCGIFBRDADDR IoctlSocket(), while forpoint-to-point networks the
address of the destination host is obtained with SIOCGIFDSTADDR.
struct sockaddr dst;
if (ifr->ifr_flags & IFF_POINTTOPOINT) -
if (IoctlSocket(s, SIOCGIFDSTADDR, (char *) ifr) < 0) -
...
"
bcopy((char *) ifr->ifr_dstaddr, (char *) &dst,
sizeof (ifr->ifr_dstaddr));
" else if (ifr->ifr_flags & IFF_BROADCAST) -
if (IoctlSocket(s, SIOCGIFBRDADDR, (char *) ifr) < 0) -
...
"
bcopy((char *) ifr->ifr_broadaddr, (char *) &dst,
sizeof (ifr->ifr_broadaddr));
"
After the appropriate ioctl's have obtained the broadcast or destination
address (now in dst), the sendto() callmay be used:
sendto(s,buf, buflen, 0, (struct sockaddr *)&dst, sizeof (dst));
"
In the above loop one sendto() occurs for every interface to which the
host is connected that supports the notion of broadcast or point-to-point
addressing. If a process only wished to send broadcastmessages on a
given network, code similar to that outlined above would be used, but the
loop would need to find the correct destination address.
Receivedbroadcast messages contain the senders address and port, as
datagram sockets are bound before a message is allowed to go out.
AmiTCP/IP specific extensions
Extensions to interface ioctls
The following ioctls are used to configure protocol and hardware specific
properties of a sana_softc interface. They are used in the AmiTCP/IP
only.
SIOCSSANATAGS Set SANA-II specific properties with a tag list.
SIOCGSANATAGS Get SANA-II specific properties into the
wiretype_parameters structure and a user tag list.
These ioctls use the following structure as a argument:
System Manual AmiTCP/IP Section 3.4 61
struct wiretype_parameters
-
ULONG wiretype; /* the wiretype of the interface */
WORD flags; /* iff_flags */
struct TagItem *tags; /* tag list user provides */
";
SIOCGARPT Getthe contents of an ARP mapping cache into a struct arpreq
table.
This ioctl takes the following arptabreq structure as an argument:
/*
* An AmiTCP/IP specific ARP table ioctl request
*/
struct arptabreq -
struct arpreq atr_arpreq; /* To identify theinterface */
long atr_size; /* # of elementsin atr_table */
long atr_inuse; /* # of elements in use */
struct arpreq *atr_table;
";
The atr_arpreq specifies the used interface. The hardware address
for the interface is returned in the arp_ha field of atr_arpreq
structure.
The SIOCGARPT ioctl reads at most atr_size entries from the cache
into the user supplied buffer atr_table, if it is not NULL. Actual
amount of returned entries is returned in atr_size. The current
amount of cached mappings is returned in the atr_inuse.
3.4.7 Socket Options
It is possible to set and get a number of options on sockets via the
setsockopt() and getsockopt() calls. These options include such things
as marking a socket for broadcasting, not to route, to linger on close,
etc. The general forms of the calls are:
setsockopt(s, level, optname, optval, optlen);
and
getsockopt(s, level, optname, optval, optlen);
The parameters to the calls are as follows: s is the socket on which
the option is to be applied. level specifies the protocol layer on which
the option is to be applied; in most cases this is the ``socket level'',
indicated by the symbolic constant SOL_SOCKET, defined in sys/socket.h.
The actual option is specified in optname, and is a symbolic constant
also defined in sys/socket.h. optval and optlen pointto the value of
the option (in most cases, whether the option is to be turned on or off),
and the length of the value of the option, respectively. For
getsockopt(), optlen is a value--resultparameter, initially set to the
62 Section 3.4 AmiTCP/IP System Manual
size of the storage area pointed to by optval, and modified upon return
to indicate the actual amount of storageused.
An example should help clarify things. It is sometimes useful to
determine the type (e.g., stream, datagram, etc.) ofan existing socket;
programs under inetd (described in section 3.4.8) may need to perform
this task. This can be accomplished as follows via theSO _TYPE socket
option and the getsockopt() call:
#include <sys/types.h>
#include <sys/socket.h>
long type, size;
size = sizeof (type);
if (getsockopt(s, SOL_SOCKET, SO_TYPE, (char *) &type, &size) < 0) -
...
"
After the getsockopt() call, type will be set to the value of the socket
type, as defined in sys/socket.h. If, for example, thesocket were a
datagram socket, type would have the value corresponding to SOCK_DGRAM.
3.4.8 Inetd
One of the daemons provided with AmiTCP/IP is inetd, the so called
``internet super--server.'' Inetd is invoked at start-up time, and
determines the servers, for which it isto listen, from the file
AmiTCP:db/inetd.conf15. Once this information has been read and a
pristine environment created, inetd proceeds to create one socket for
each service it is to listen for, binding the appropriate port number to
each socket.
Inetd then performs a select() on all these sockets for read
availability, waiting for somebody wishing a connection to the service
corresponding to that socket. Inetd then performs an accept() on the
socket in question, releases the socketwith a ReleaseSocket() call and
starts the appropriate server.
Servers making use of inetd are considerably simplified, as inetd takes
care of the majority of the work required in establishing a connection.
The server invoked by inetd expects thesocket connected to its client to
be found by calling ObtainSocket(). The client socketID for the server
is found in a DaemonMessage structure given to the server process.
Usually the netlib:autoinitd.o module takes care of obtaining the client
socket into global variable server_socket. For practical purposes the
code might assume this socket to be 0.
One callwhich may be of interest to individuals writing servers under
inetd is the getpeername() call, which returns the address of the peer
(process) connected on the other end ofthe socket. For example, to log
the Internet address in ``dot notation''(e.g., ``128.32.0.4'') of a
________________________________
15In UNIX systems /etc/inetd.conf.
System Manual AmiTCP/IP Section 3.5 63
client connected to a server under inetd, the following code might be
used:
struct sockaddr_in name;
int namelen = sizeof (name);
...
if (getpeername(0, (struct sockaddr *)&name, &namelen) < 0) -
syslog(LOG_ERR, "getpeername: %m");
exit(1);
" else
syslog(LOG_INFO, "Connection from %s", inet_ntoa(name.sin_addr));
...
While the getpeername() call is especially useful when writing programs
to run with inetd, it can be used underother circumstances.
Sources for a very simple TCP protocol server is included with
AmiTCP/IP as an example.
3.5 Deviation From Berkeley Sockets
This section discusses the differences between the API of the AmiTCP/IP
and the 4.3BSD. They are not so numerousas it might seem to, but worth
taking attention to when porting existing 4.3BSD software to AmiTCP/IP.
3.5.1 Opening and Closing the Shared Library
Since the API is provided as a shared library, it must be opened to be
able to access the functions it provides. Note that any two tasks may
not share a socket library base, since the base contains task specific
information.
AmiTCP/IPdoes resource tracking based on the information stored in a
library base, so it is essential that the library is closed after use,
since the resources used by the base aregone if the application exits
without closing the base.
See section 3.1.2 for examples and more discussion on the subject.
3.5.2 Naming Conventions of the API Functions
The API functions which preserve the semantics of the BSD calls are named
the same as the original functions. In the name of binary compatibility
between different C compilers the functions which either take a structure
as an argument or return a structure asa value had to be changed not to
do so. These functions are named differently; all words in these
function names begin with an upper caseletter. Inlinefunctions16 are
provided with the original semantics, however. This makes it possible to
keep using the original functions when writing the code and still be
binary compatible. The inline functions are mostly trivial; for example
the select() call is actually an inlinewhich calls WaitSelect() with
last argument as NULL.
________________________________
16Or linker stubs in compilers with no inline functions.
64 Section 3.5 AmiTCP/IP System Manual
This is amatter which should be totally invisible for C users, but
assembler programmers should take attention and be sure to pass arguments
as described in the function reference for the non-inline versions.
3.5.3 errno
Unix libraries return error values in aglobal variable named errno.
Since a shared library cannot know the address of any variables of an
application, the address of the errno must be explicitly told to the
AmiTCP/IP. An alternative is to use Errno() call to fetch the error
value, but since the first method needsno modifications to the existing
sources (besides calling SetErrnoPtr() once in the beginning), it is the
preferred method. Section 3.1.2 contains examples andmore discussion
about the matter.
3.5.4 NewField in the sockaddr Structures
Since AmiTCP/IP is based on the BSD Net/2 release, it has few
differences to the 4.3BSD. Most notableone is that the sockaddr and
sockaddr_in structureshave a new field telling the length of the
structure. These are named as sa_len and sin_len respectively. These
fields are used by the AmiTCP/IP to determine the real length of the
address given.
In addition the sockaddr_in structure has a field named sin_zero, which
should be initialized to zero before passed to the AmiTCP/IP, since any
garbage left there will be used by the routing facility (which obviously
leads to undesired behaviour).
3.5.5 Linger Time
The unit of the linger time of a socketis a second. The Net/2 code
seemed to use ticks17.
3.5.6 Transferring Sockets from a Task to Another
Since AmigaOS has no fork() call, in which the child process inherits the
file descriptors, and hence sockets, a mechanism for transferring sockets
from a task to another must be provided. This is accomplished by the
calls ReleaseSocket(), ReleaseCopyOfSocket() and ObtainSocket(), which
release a socket, a copy of a socket andobtain a released socket,
respectively. An id is given to a socket placed in thelist of released
sockets. This id can be either unique or be based on aservice number in
cases where it is irrelevant which instance of the server process for the
service in question obtains the socket. If an unique id is used, the
releasing task is responsible of transferring the id to the obtaining
task.
________________________________
17One tick is 1/hz:th of a second, where hz is the frequency of the
electricity of the wall socket.
System Manual AmiTCP/IP Section 3.5 65
This feature affects the server processes only, since the clients
usually create the socket(s) on their own.
3.5.7 Ioctl Differences
The Unix ioctl() function is renamed asIoctlSocket() in AmiTCP/IP to
avoid name clashes with some C runtime libraries.
Followingsummarizes other differences in the ioctl calls:
1. FIOCLEX and FIONCLEX are silently ignored, that is, they are
accepted, but have no effect. Whether sockets should be closed on
exec() or not is irrelevant, since AmigaOS has no such feature (see
discussion about fork() above).
2. FIOSETOWN and SIOCSPGRP take a pointer to a struct Task * as an
argument instead of a pointer to a process (or group) id. Note that
if the task in question has not opened the bsdsocket.library the
owner of the precess is set to NULL (disabled). The task pointer is
used as the receiver of the asynchronous notification signals if
asynchronous notification is enabled.
3. FIOGETOWN and SIOCGPGRP take a pointer to a struct Task * as an
argument in which the current task pointer of the owner of the socket
in question is placed on return.
3.5.8 Signal Handling
There is a fundamental difference between BSD Unix and Amiga signal
handling and the system call interface. In the Unix systems a received
signal may interrupt a process executinga system call. If there is a
signal handler installed, it can be executed before the system call
returns to the main execution branch with an error code.
However,there are some system calls which may not be interrupted. If
a Unix process has a negative priority,tsleep() does not wake up until
the specified condition is met.
The interrupted system call does not have any unrecoverable effects,
the execution of the program may continue after the errno is checked
against other errors than EINTR.
In the AmigaOS, Exec, there are no specific system calls. All OS
functions are provided by shared libraries. There areeither no separate
kernel and user memory spaces, the one common memory space is shared by
all processes. The IO system is based on messages, which are implemented
as shared memory areas. When a program receives a message to a port, it
is delivered a signal associated with the port.
While itis possible to use signal handlers with Exec, they are even
more dangerous to use and restricted than in Unix systems. This is not
recommended, since the exception handlermust behave like any real
interrupt handler. Calls provided by AmiTCP/IP are notcallable from
interrupts. Further, it is not possible to interrupt asystem call
implemented as a shared library function.
The application must itself react on receipt of the signals. The
recommended way of handling these signals is by the normal Wait() of by
66 Section 3.5 AmiTCP/IP System Manual
AmiTCP/IP call WaitSelect(), which allows an application to specify a
signal mask which should abort the selection. The application then
checks the received signals and calls appropriate handler for the signal.
3.5.9 Asynchronous I/O
AmigaOS does not have any reserved signals for networking, such as SIGIO
or SIGURG in Unix systems, and so the scheme used in asynchronous
notification must be changed a little.
The application can set a group of signal masks, with function named
SetSocketSignals(), to be used by the AmiTCP/IP. First argument
specifies the signal mask which should break the blocking of the blocking
socket calls. It is by default set to the signal for CTRL-C. Second
argument specifies the signal(s) to be sent when asynchronous
notification for readiness to read is necessary. Thismask lets the
application define which signal should be used as replacement for SIGIO
signal of the Unix systems. Third and last argument specifies the
corresponding mask for the asynchronousnotification of urgent
(out-of-band) data (SIGURG). These lasttwo masks are zero by default.
Note thatthere is no way to query the current settings of these
signals form the AmiTCP/IP, so the application must store the signal
numbers (or masks) for later use. Also note that the break mask must be
explicitly given if SetSocketSignals() is called, since the values
supplied override the default settings.
3.5.10 Constructing an Event Loop
Amiga programs are often constructed around an event loop, in which
Wait() function is used to wait for somesubset of given signals to
arrive. When a signal is received, some actions are taken and if IO is
performed, it is usually asynchronous.
Many Unixprograms use to do synchronous IO and let the signal handlers
to handle special events (window size changes, timeouts, etc.). This can
be emulated to some extent with AmigaOS,since it is possible to specify
an exeption function to handle receptionof given signals. This is very
limited, though, since the exeption codeis executed at true interrupt
level, and may thus pre-empt the main process in an arbitrary location.
Also note that a very limited set of shared library functions can be
called while in interrupt, especially note that any AmiTCP/IP function
may NOT be called from interrupt code.
AmiTCP/IPoffers remedy for this, however. The application can use
WaitSelect() to handle both Amiga signals and socket IO multiplexing.
Selecting assures that the following socket calls will not block18.
Another possiblility is to use signal driven socket IO (see section
3.4.3).
Yet another possibility is to specify a special break mask with
SetSocketSignals() function. The signals in the mask cause any blocking
socket IO routine to return with the error code EINTR. Note that the
________________________________
18See NOTES section of the reference for the WaitSelect().
System Manual AmiTCP/IP Section 3.5 67
signals are not cleared in this procedure. The Wait()with the same
signal mask can be used to determine (and clear) the received signals.
This allows the usage of synchronous socket IO, but the EINTR error code
must be checked after each failing call.
3.5.11 ''Killing'' the Processes
In AmigaOS the applications must co-operate with the OS for the user to
be able to stop them. This is why the blocking operations of the
AmiTCP/IP can be aborted. By default the reception ofCTRL-C signal
aborts any blocking call. The call returns an error value (in errno) of
EINTR when aborted. In addition the signal which caused the break will
remain set for the application to be able to react on it in its normal
event processing. This means that the application neednot specially
check for EINTR after every socket callas long as they eventually check
for the break signal.
All sockets left open by the application are closed by the
CloseLibrary() call. You may left the sockets open when aborting the
program, because the socket library is closed automatically during the
exit process if either autotermination function (specific to SAS C) or
ANSI atexit() function is installed before the exit is done. .
The signals which cause the abort can be set with the
SetSocketSignals() call. The break signal mask is given as the first
argument. Calling this function discards the previousvalues of the
sockets signal masks. Aborting can be disabled by giving the mask as 0L.
See section 3.5.9 for more discussion about the SetSocketSignals() call.
3.5.12 WaitSelect()
In AmiTCP/IP no other than socket I/O can be multiplexed with the
select() call. This may be a major pain as I/O is normally multiplexed
with an Wait() loop, waiting for given signals to arrive. This is the
motivation for the WaitSelect() call. It combines theselection and
waiting in a single call19. The WaitSelect() takes one argument in
addition to the normal select() call. It is a pointerto signal mask to
wait for in addition to the signals thatthe AmiTCP/IP uses internally.
If any of these signals is received, they are returned as a result in the
same signal mask. Signals specified in the given signal mask override
the signals of the break mask (see previous section). If the same signal
is specified in both the SIGINTR mask and the mask given to the WaitSelect(),
the reception of the signal causes it tobe cleared and returned in the mask
as the result.
WaitSelect() can be used as replacement for the Wait() in applications
which require to multiplex both socket related and other Amiga I/O.
________________________________
19This feature was really easy to implement, since AmiTCP/IP uses a Wait()
to wait for I/O events itself.
68 Section 3.5 AmiTCP/IP System Manual
Appendix B
API Function Reference
This appendix is a complete reference tothe functions and concepts
provided by the AmiTCP/IP system.
Table of Contents
Standard BSD Style Socket Functions
accept : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : *
*: : : : : : : : : 130
bind : : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : : :*
* : : : : : : : : : 132
CloseSocket : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : *
*: : : : : : : : 133
connect : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : *
*: : : : : : : : : 134
Dup2Socket : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : *
*: : : : : : : : 136
getpeername : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : *
*: : : : : : : : 137
getsockname : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : *
*: : : : : : : : 138
getsockopt : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : *
*: : : : : : : : 139
IoctlSocket : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : *
*: : : : : : : : 142
listen : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : *
*: : : : : : : : : 144
recv : : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : : :*
* : : : : : : : : : 145
recvfrom : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :*
* : : : : : : : : 145
select : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : *
*: : : : : : : : : 147
send : : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : : :*
* : : : : : : : : : 150
sendto : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : *
*: : : : : : : : : 150
setsockopt : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : *
*: : : : : : : : 139
shutdown : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :*
* : : : : : : : : 152
socket : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : *
*: : : : : : : : : 153
WaitSelect : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : *
*: : : : : : : : 147
Other BSD Functions Related to Sockets
getdtablesize : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
* : : : :: : : 156
Syslog : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : *
*: : : : : : : : : 157
Network Data and Address Manipulation
inet_addr : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
* : : : : : : :: 159
Inet_LnaOf: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
* : : : :: : : : 159
inet_lnaof: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
* : : : :: : : : 159
128
System Manual AmiTCP/IP Section B.0 129
inet_MakeAddr : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
* : : : : : : :159
inet_makeaddr : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
* : : : : : : :159
Inet_NetOf: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
* : : : :: : : : 159
inet_netof: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
* : : : :: : : : 159
inet_network : : : : : : : : : : : : : : : : : : : : : : :: : : : : : :*
* : : : : : : : 159
Inet_NtoA : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
* : : : : : : :: 159
inet_ntoa : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
* : : : : : : :: 159
Network, Protocol and Service Queries
gethostbyaddr : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
* : : : :: : : 162
gethostbyname : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
* : : : :: : : 162
getnetbyaddr : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :*
* : : : : : : : 164
getnetbyname : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :*
* : : : : : : : 164
getprotobyname : : : : : : :: : : : : : : : : : : : : : : : : : : : : *
*: : : : : : : 166
getprotobynumber : : : : : : : : : : : : : : : : : :: : : : : : : : : :*
* : : : : : : 166
getservbyname : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
* : : : :: : : 167
getservbyport : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
* : : : :: : : 167
AmiTCP/IP Specific Extensions
Errno : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
* : : :: : : : : : 169
ObtainSocket : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :*
* : : : : : : : 170
ReleaseCopyOfSocket : :: : : : : : : : : : : : : : : : : : : : : : : : *
*: : : : : : 171
ReleaseSocket : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
* : : : :: : : 172
SetDTableSize : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
* : : : :: : : 173
SetErrnoPtr : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : *
*: : : : : : : : 174
SetSocketSignals : : : : : : : : : : : : : : : : : :: : : : : : : : : :*
* : : : : : : 175
130 Section B.1 AmiTCP/IP System Manual
B.1 Standard BSD Style Socket Functions
B.1.1 accept()
NAME
accept -accept a connection on a socket
SYNOPSIS
#include <sys/types.h>
#include <sys/socket.h>
ns = accept(s, addr, addrlen)
D0 D0 A0 A1
long accept(long, struct sockaddr *, long *);
FUNCTION
The argument s is a socket that has been created with
socket(),bound to an address with bind(), and is listen-
ing for connections after a listen(). accept() extracts the
first connection on the queue of pending connections,
creates anew socket with the same properties of s and allo-
cates a new socket descriptor for the socket. If no pending
connections are present on the queue, and the socket is not
marked as non-blocking, accept() blocks the caller until a
connection is present. If the socket is marked non-blocking
and no pending connections are present on the queue,
accept()returns an error as described below. The accepted
socket isused to read and write data to and from the socket
which connected to this one; it is not used to accept more
connections. The original socket s remains open for accept-
ing further connections.
The argument addr is a result parameter that is filled in
with the address of the connecting entity, as known to the
communications layer. The exact format of the addr parame-
ter is determined by the domain in which the communication
is occurring. The addrlen is a value-result parameter; it
should initially contain the amount of space pointed to by
addr; onreturn it will contain the actual length (in bytes)
of the address returned. This call is used with
connection-based socket types, currently with SOCK_STREAM.
It is possible to select() a socket for the purposes of
doing anaccept() by selecting it for read.
RETURN VALUES
accept()returns a non-negative descriptor for the accepted
socket onsuccess. Onfailure, it returns -1 and sets errno
to indicate the error.
System Manual AmiTCP/IP Section B.1 131
ERRORS
EBADF - The descriptoris invalid.
EINTR - The operation was interrupted by a break
signal.
EOPNOTSUPP - The referencedsocket is not of type
SOCK_STREAM.
EWOULDBLOCK - The socket is marked non-blocking and no con-
nections are present to be accepted.
SEE ALSO
bind(), connect(), listen(), select(), SetSocketSignals(),
socket()
132 Section B.1 AmiTCP/IP System Manual
B.1.2 bind()
NAME
bind - bind a name to a socket
SYNOPSIS
#include <sys/types.h>
#include <sys/socket.h>
success =bind(s, name, namelen)
D0 D0 A0 D1
long bind(long, struct sockaddr *, long);
FUNCTION
bind() assigns a name to an unnamed socket. When a socket
is created with socket(2) it exists in a name space (address
family) but has no name assigned. bind() requests that the
name pointed to by name be assigned to the socket.
RETURN VALUES
0 - on success.
-1 - on failure and sets errno to indicate the error.
ERRORS
EACCES - The requested address is protected, and
the current user has inadequate permis-
sion to access it.
EADDRINUSE - The specified address is already in use.
EADDRNOTAVAIL - The specified address is not available
from the local machine.
EBADF -s is not a valid descriptor.
EINVAL - namelen is not the size of a valid
address for the specified address fam-
ily.
The socket is already bound to an
address.
SEE ALSO
connect(), getsockname(), listen(), socket()
NOTES
The rulesused in name binding vary between communication
domains.
System Manual AmiTCP/IP Section B.1 133
B.1.3 CloseSocket()
NAME
CloseSocket - delete a socket descriptor
SYNOPSIS
success =CloseSocket(s)
D0 D0
long CloseSocket(long);
FUNCTION
CloseSocket() deletes a descriptor from the library base
socket reference table. Ifs is the last reference to the
underlying object, then the object will be deactivated and
socket (see socket()), associated naming information and
queued data are discarded.
All sockets are automatically closed when the socket library
is closed, but closing sockets as soon as possible is
recommended to save system resources.
RETURN VALUES
0 on success.
-1 on failure and sets errnoto indicate the error.
ERRORS
EBADF -s is not an active socket descriptor.
EINTR -linger on close was interrupted.
The socket is closed, however.
SEE ALSO
accept(),SetSocketSignals(), shutdown(), socket(),
exec.library/CloseLibrary()
134 Section B.1 AmiTCP/IP System Manual
B.1.4 connect()
NAME
connect -initiate a connection on a socket
SYNOPSIS
#include <sys/types.h>
#include <sys/socket.h>
success =connect(s, name, namelen)
D0 D0 A0 D1
long connect(long, struct sockaddr *, long);
FUNCTION
The parameter s is a socket. If it is of type SOCK_DGRAM,
then this call specifies the peer with which the socket is
to be associated; this address is that to which datagrams
are to be sent, and the only address from which datagrams
are to bereceived. Ifit is of type SOCK_STREAM, then this
call attempts to make a connection to another socket. The
other socket is specified by name which is an address in the
communications space of the socket. Each communications
space interprets the name parameter in its own way. Gen-
erally, stream sockets may successfully connect() only once;
datagramsockets may use connect() multiple times to change
their association. Datagram sockets may dissolve the asso-
ciation by connecting to an invalid address, such as a null
address.
RETURN VALUES
0 on success.
-1 on failure and sets errnoto indicate the error.
ERRORS
EADDRINUSE - The address is already in use.
EADDRNOTAVAIL - The specified address is not available
on the remote machine.
EAFNOSUPPORT - Addresses in the specified address fam-
ily cannot be used with this socket.
EALREADY - The socket is non-blocking and a previ-
ous connection attempt has not yet been
completed.
EBADF -s is not a valid descriptor.
ECONNREFUSED - The attempt to connect was forcefully
System Manual AmiTCP/IP Section B.1 135
rejected. The calling program should
CloseSocket() the socket descriptor, and
issue another socket() call to obtain a
new descriptor before attempting another
connect() call.
EINPROGRESS - The socket is non-blocking and the con-
nection cannot be completed immediately.
It is possible to select() for comple-
tion by selecting the socket for writ-
ing.
EINTR -The operation was interrupted by a break
signal.
EINVAL - namelen is not the size of a valid
address for the specified address fam-
ily.
EISCONN The socket is already connected.
ENETUNREACH - The network is not reachable from this
host.
ETIMEDOUT - Connection establishment timed out
without establishing a connection.
SEE ALSO
accept(),CloseSocket(), connect(), getsockname(), select(),
socket()
136 Section B.1 AmiTCP/IP System Manual
B.1.5 Dup2Socket()
NAME
Dup2Socket - duplicate a socket descriptor
SYNOPSIS
newfd = Dup2Socket(fd1, fd2)
D0 D0 D1
long Dup2Socket(long, long);
DESCRIPTION
Dup2Socket() duplicates an existing socket descriptor.
theargument fd1 is small non-negative value that indexes
thesocket on SocketBase descriptor table. The value must
beless than the size of the table, which is returned by
getdtablesize(). fd2 specifies the desired value of the new
descriptor. If descriptor fd2 is already in use, it is
first deallocated as if it were closed by CloseSocket(). If
thevalue if fd2 is -1, the new descriptor used and returned
isthe lowest numbered descriptor that is not currently in
useby the SocketBase.
RETURN VALUES
Dup2Socket() returns a new descriptor on success. On failure
-1is returned and errno is set to indicate the error.
ERRORS
EBADF fd1 or fd2 is not a valid active descriptor.
EMFILE Too many descriptors are active.
SEE ALSO
accept(), CloseSocket(), getdtablesize(), SetDtableSize(),
socket()
System Manual AmiTCP/IP Section B.1 137
B.1.6 getpeername()
NAME
getpeername - get name of connected peer
SYNOPSIS
success = getpeername(s, name, namelen)
D0 D0 A0 A1
long getpeername(long, struct sockaddr *, long *);
FUNCTION
getpeername() returns the name of the peer connected to
socket s. The long pointed to by the namelen parameter
should be initialized to indicate the amount of space
pointed to by name. On return it contains the actual size
of the name returned (in bytes). The name is truncated if
the buffer provided is too small.
RETURN VALUE
A 0 is returned if the call succeeds, -1 if it fails.
ERRORS
EBADF - The argument sis not a valid descriptor.
ENOBUFS - Insufficient resources were available in the
system to perform the operation.
ENOTCONN - The socket is not connected.
SEE ALSO
accept(),bind(), getsockname(), socket()
138 Section B.1 AmiTCP/IP System Manual
B.1.7 getsockname()
NAME
getsockname - get socket name
SYNOPSIS
success =getsockname(s, name, namelen)
D0 D0 A0 A1
long getsockname(long, struct sockaddr *, long *);
FUNCTION
getsockname() returns the current name for the specified
socket. The namelen parameter should be initialized to
indicatethe amount of space pointed to by name. On return
it contains the actual size of the name returned (in bytes).
DIAGNOSTICS
A 0 is returned if the call succeeds, -1 if it fails.
ERRORS
The callsucceeds unless:
EBADF s is not a valid descriptor.
ENOBUFS Insufficient resources were available in the
system to perform the operation.
SEE ALSO
bind(), getpeername(), socket()
System Manual AmiTCP/IP Section B.1 139
B.1.8 getsockopt()
NAME
getsockopt, setsockopt - get and set options on sockets
SYNOPSIS
#include <sys/types.h>
#include <sys/socket.h>
success = getsockopt(s, level, optname, optval, optlen)
D0 D0 D1 D2 A0 A1
long getsockopt(long, long, long, caddr_t, long *);
success = setsockopt(s, level, optname, optval, optlen)
D0 D0 D1 D2 A0 D3
long setsockopt(long, long, long, caddr_t, long);
FUNCTION
getsockopt() and setsockopt() manipulate options associated
with a socket. Options may exist at multiple protocol lev-
els; theyare always present at the uppermost ``socket''
level.
When manipulating socket options the level at which the
option resides and the name of the option must be specified.
To manipulate options at the ``socket'' level, level is
specifiedas SOL_SOCKET. To manipulate options at any other
level theprotocol number of the appropriate protocol con-
trolling the option is supplied. For example, to indicate
that an option is to be interpreted by the TCP protocol,
level should be set to the protocol number of TCP.
The parameters optval and optlen are used to access option
values for setsockopt(). For getsockopt() they identify a
buffer inwhich the value for the requested option(s) are to
be returned. For getsockopt(), optlen is a value-result
parameter, initially containing the size of the buffer
pointed to by optval, and modified on return to indicate the
actual size of the value returned. If no option value is to
be supplied or returned, optval may be supplied as 0.
optname and any specified options are passed uninterpreted
to the appropriate protocol module for interpretation. The
include file <sys/socket.h> contains definitions for
``socket'' level options, described below. Options at other
protocol levels vary in format and name.
Most socket-level options take an int parameter for optval.
For setsockopt(), the parameter should be non-zero to enable
140 Section B.1 AmiTCP/IP System Manual
a booleanoption, or zero if the option is to be disabled.
SO_LINGER uses a struct linger parameter, defined in
<sys/socket.h>, which specifies the desired state of the
option and the linger interval (see below).
The following options are recognized at the socket level.
Except as noted, eachmay be examined with getsockopt() and
set withsetsockopt().
SO_DEBUG - toggle recording of debugging
information
SO_REUSEADDR - toggle local address reuse
SO_KEEPALIVE - toggle keep connections alive
SO_DONTROUTE - toggle routing bypass for outgoing
messages
SO_LINGER - linger on close if data present
SO_BROADCAST - toggle permission to transmit
broadcast messages
SO_OOBINLINE - toggle reception of out-of-band
data in band
SO_SNDBUF - set buffer size for output
SO_RCVBUF - set buffer size for input
SO_TYPE - get the type of the socket (get
only)
SO_ERROR - get and clear error on the socket
(get only)
SO_DEBUG enables debugging in the underlying protocol
modules. SO_REUSEADDR indicates that the rules used in
validating addresses supplied in a bind() call should allow
reuse oflocal addresses. SO_KEEPALIVE enables the periodic
transmission of messages on a connected socket. Should the
connected party fail to respond to these messages, the con-
nection is considered broken. If the process is
waiting in select() when the connection is broken, select()
returns true for any read or write events selected for the
socket. SO_DONTROUTE indicates that outgoing messages
should bypass the standard routing facilities. Instead,
messages are directed to the appropriate network interface
accordingto the network portion of the destination address.
SO_LINGERcontrols the action taken when unsent messags are
queued on socket and a CloseSocket() is performed. If the
socket promises reliable delivery of data and SO_LINGER is
set, the system will block the process on the close
attempt until it is able to transmit the data or until it
decides it is unable to deliver the information (a timeout
period, in seconds, termed the linger interval, is specified
in the set- sockopt() call when SO_LINGER is requested). If
SO_LINGER is disabled and a CloseSocket() is issued, the
System Manual AmiTCP/IP Section B.1 141
system will process the close in a manner that allows the
process to continue as quickly as possible.
The option SO_BROADCAST requests permission to send broad-
cast datagrams on the socket. Broadcast was a privileged
operationin earlier versions of the system. With protocols
that support out-of-band data, the SO_OOBINLINE option
requeststhat out-of-band data be placed in the normal data
input queue as received; it will then be accessible with
recv() orread() calls without the MSG_OOB flag. SO_SNDBUF
and SO_RCVBUF are options to adjust the normal buffer sizes
allocatedfor output and input buffers, respectively. The
buffer size may be increased for high-volume connections, or
may be decreased to limit the possible backlog of incoming
data. The system places an absolute limit on these values.
Finally,SO_TYPE and SO_ERROR are options used only with
getsockopt(). SO_TYPE returns the type of the socket, such
as SOCK_STREAM; it is useful for servers that inherit sock-
ets on startup. SO_ERROR returns any pending error on the
socket and clears the error status. It may be used to check
for asynchronous errors on connected datagram sockets or for
other asynchronous errors.
RETURN VALUES
0 - on success.
-1 - on failure and set errno to indicate the error.
ERRORS
EBADF -s is not a valid descriptor.
ENOPROTOOPT - The option is unknown at the level indi-
cated.
SEE ALSO
IoctlSocket(), socket()
BUGS
Several of the socket options should be handled at lower
levels ofthe system.
142 Section B.1 AmiTCP/IP System Manual
B.1.9 IoctlSocket()
NAME
IoctlSocket - control sockets
SYNOPSIS
#include <sys/types.h>
#include <sys/ioctl.h>
value = IoctlSocket(fd, request, arg)
D0 D0 D1 A0
long IoctlSocket(long, long, caddr_t);
FUNCTION
IoctlSocket() performs a special function on the object referred
to by theopen socketdescriptor fd. Note: the setsockopt()
call (seegetsockopt()) is the primary method for operating
on sockets as such, rather than on the underlying protocol
or network interface.
For mostIoctlSocket() functions, arg is a pointer to data to
be used by the function or to be filled in by the function.
Other functions may ignore arg or may treat it directly as a
data item; they may, for example, be passed an int value.
The following requests are supported:
FIOASYNC The argument is a pointer to a long.
Set or clear asynchronous I/O. If the
value of that long is a 1 (one) the
descriptor is set for asynchronous I/O.
If the value of that long is a 0 (zero)
the descriptor is cleared for asynchro-
nous I/O.
FIOCLEX
FIONCLEX Ignored, no use for close-on-exec flag
in Amiga.
FIOGETOWN
SIOCGPGRP The argument is pointer to struct Task*.
Set the value of that pointer to the
Task that is receiving SIGIO or SIGURG
signals for the socket referred to by
the descriptor passed to IoctlSocket().
FIONBIO The argument is a pointer to a long.
Set or clear non-blocking I/O. If the
System Manual AmiTCP/IP Section B.1 143
value of that long is a 1 (one) the
descriptor is set for non-blocking I/O.
If the value of that long is a 0 (zero)
the descriptor is cleared for non-
blocking I/O.
FIONREAD The argument is a pointer to a long.
Set the value of that long to the number
of immediately readable characters from
the socket fd.
FIOSETOWN
SIOCSPGRP The argument is pointer to struct Task*,
pointer to the task that will subseq-
uently receive SIGIO or SIGURG signals
for the socket referred to by the
descriptor passed.
SIOCCATMARK The argument is a pointer to a long.
Set the value of that long to 1 if the
read pointer for the socket referred to
by the descriptor passed to
IoctlSocket() points to a mark in the
data stream for an out-of-band message,
and to 0 if it does not point to a mark.
RETURN VALUES
IoctlSocket() returns 0 on success for most requests. Some
specialized requests may return non-zero values on success; On
failure, IoctlSocket()returns -1 and sets errno to indicate
the error.
ERRORS
EBADF fd is not a valid descriptor.
EINVAL request or arg is not valid.
IoctlSocket() will also fail if the object on which the function
is being performed detects an error. In this case, an error
code specific to the object and the function will be
returned.
SEE ALSO
getsockopt(), SetSocketSignals(), setsockopt()
144 Section B.1 AmiTCP/IP System Manual
B.1.10 listen()
NAME
listen -listen for connections on a socket
SYNOPSIS
success =listen(s, backlog)
D0 D0 D1
long listen(long, long);
FUNCTION
To accept connections, a socket is first created with
socket(), a backlog for incoming connections is specified
with listen() and then the connections are accepted with
accept(). The listen() call applies only to socket of
type SOCK_STREAM.
The backlog parameter defines the maximum length the queue
of pending connections may grow to. If a connection request
arrives with the queue full the client will receive an error
with an indication of ECONNREFUSED.
RETURN VALUES
0 on success.
-1 on failure and sets errno to indicate the error.
ERRORS
EBADF -s is not a valid descriptor.
EOPNOTSUPP - The socketis not of a type that sup-
ports listen().
SEE ALSO
accept(),connect(), socket()
BUGS
The backlog is currently limited (silently) to 5.
System Manual AmiTCP/IP Section B.1 145
B.1.11 recv()
NAME
recv, recvfrom, - receive a message from a socket
SYNOPSIS
#include <sys/types.h>
#include <sys/socket.h>
nbytes = recv(s, buf, len, flags)
D0 D0 A0 D1 D2
long recv(long, char *, long, long);
nbytes = recvfrom(s, buf, len, flags, from, fromlen)
D0 D0 A0 D1 D2 A1 A2
long recvfrom(long, char *, long, long,
struct sockaddr *, long *);
FUNCTION
s is a socket created with socket(). recv() and recvfrom(),
are used to receive messages from another socket. recv()
may be used only on a connected socket (see connect()),
while recvfrom() may be used to receive data on a socket
whether it is in a connected state or not.
If from is not a NULL pointer, the source address of the
message is filled in. fromlen is a value-result parameter,
initialized to the size of the buffer associated with from,
and modified on return to indicate the actual size of the
address stored there. The length of the message is
returned. If a message is too long to fitin the supplied
buffer, excess bytes may be discarded depending on the type
of socketthe message is received from (see socket()).
If no messages are available at the socket, the receive call
waits for a message to arrive, unless the socket is non-
blocking(see IoctlSocket()) in which case -1 is returned
with theexternal variable errno set to EWOULDBLOCK.
The select() call may be used to determine when more data
arrive.
The flagsparameter is formed by ORing one or more of the
following:
MSG_OOB - Read any "out-of-band" data present on the
socket, rather than the regular "in-band"
data.
146 Section B.1 AmiTCP/IP System Manual
MSG_PEEK - "Peek" at the data present onthe socket; the
data are returned, but not consumed, so that
a subsequent receive operation will see the
same data.
RETURN VALUES
These calls return the number of bytes received, or -1 if an
error occurred.
ERRORS
EBADF -s is an invalid descriptor.
EINTR -The operation was interrupted by a break
signal.
EWOULDBLOCK - The socket is marked non-blocking and
the requested operation would block.
SEE ALSO
connect(), getsockopt(), IoctlSocket(), select(), send(),
SetSocketSignals(), socket()
System Manual AmiTCP/IP Section B.1 147
B.1.12 select()
NAME
select --synchronous I/O multiplexing (stub/inline function)
WaitSelect -- select() with Amiga Wait() function.
SYNOPSIS
#include <sys/types.h>
#include <sys/time.h>
n = select (nfds, readfds, writefds, exceptfds, timeout)
long select(long, fd_set *, fd_set *, fd_set *,
struct timeval *);
n = WaitSelect (nfds, readfds, writefds, exceptfds, timeout,
D0 D0 A0 A1 A2 A3
sigmp)
D1
long WaitSelect(long, fd_set *, fd_set *, fd_set *,
struct timeval *, long *);
FD_SET (fd, &fdset)
FD_CLR (fd, &fdset)
FD_ISSET(fd, &fdset)
FD_ZERO (&fdset)
long fd;
fd_set fdset;
DESCRIPTION
select()examines the socket descriptor sets whose addresses
are passed in readfds, writefds, and exceptfds to see if
some of their descriptors are ready for reading, ready for
writing, or have an exceptional condition pending. nfds is
the number of bits to be checked in each bit mask that
representa file descriptor; the descriptors from 0 through
(nfds - 1) in the descriptor sets are examined. On return,
select() replaces the given descriptor sets with subsets
consisting of those descriptors that are ready for the
requestedoperation. The total number of ready descriptors
in all the sets is returned.
WaitSelect() also takes a signal mask which is waited during
normal select() operation. If one of these singals is recei-
ved, WaitSelect() returns and has re-set the signal mask
to returnthose signals that have arrived. Normal select()
return values are returned.
The descriptor sets are stored as bit fields in arrays of
integers. The following macros are provided for manipulat-
148 Section B.1 AmiTCP/IP System Manual
ing suchdescriptor sets: FD_ZERO (&fdset) initializes a
descriptor set fdset to the null set. FD_SET(fd, &fdset )
includesa particular descriptor fd in fdset. FD_CLR(fd,
&fdset) removes fd from fdset. FD_ISSET(fd, &fdset) is
nonzero if fd is a member of fdset, zero otherwise. The
behavior of these macros is undefined if a descriptor value
is less than zero or greater than or equal to FD_SETSIZE,
which is normally at least equal to the maximum number of
descriptors supported by the system.
If timeout is not a NULL pointer, it specifies a maximum
interval to wait for the selection to complete. If timeout
is a NULL pointer, the select blocks indefinitely. To
effect a poll, the timeout argument should be a non-NULL
pointer,pointing to a zero-valued timeval structure.
Any of readfds, writefds, and exceptfds may be given as NULL
pointersif no descriptors are of interest.
Selectingtrue for reading on a socket descriptor upon which
a listen() call has been performed indicates that a subse-
quent accept() call on that descriptor will not block.
RETURN VALUES
select()returns a non-negative value on success. A positive
value indicates the number of ready descriptors in the
descriptor sets. 0 indicates that the time limit referred to
by timeout expired or that the operation was interrupted
either bya break signal or by arrival of a signal specified
in *sigmp. On failure, select() returns -1, sets errno to
indicatethe error, and the descriptor sets are not changed.
ERRORS
EBADF - One of the descriptor sets specified an
invalid descriptor.
EINTR - one of the signals in SIGINTR mask (see Set-
SocketSignals()) is set and it was not
requested in WaitSelect() call.
EINVAL - A component of the pointed-to time limit is
outside the acceptable range: t_sec must be
between 0 and 10^8,inclusive. t_usec must be
greater than or equal to 0, and less than
10^6.
SEE ALSO
accept(), connect(), getdtablesize(), listen(), recv(),
send(), SetDTableSize(), SetSocketSignals()
NOTES
System Manual AmiTCP/IP Section B.1 149
Under rare circumstances, select() may indicate that a
descriptor is ready for writing when in fact an attempt to
write would block. This can happen if system resources
necessary for a write are exhausted or otherwise unavail-
able. Ifan application deems it critical that writes to a
file descriptor not block, it should set the descriptor for
non-blocking I/O using the FIOASYNC request to IoctlSocket().
Default system limit for open socket descriptors is
currently 64. However, in order to accommodate programs
which might potentially use a larger number of open files
with select, it is possible to increase this size within a
program by providing a larger definition of FD_SETSIZE
before the inclusion of <sys/types.h> and use
SetDTableSize(FD_SETSIZE) call directly after OpenLibrary().
BUGS
select()should probably return the time remaining from the
original timeout, if any, by modifying the time value in
place. This may be implemented in future versions of the
system. Thus, it is unwise to assume that the timeout
pointer will be unmodified by the select() call.
150 Section B.1 AmiTCP/IP System Manual
B.1.13 send()
NAME
send, sendto - send a message from a socket
SYNOPSIS
#include <sys/types.h>
#include <sys/socket.h>
nbytes =send(s, msg, len, flags)
D0 D0 A0 D1 D2
int send(int, char *, int, int);
nbytes =sendto(s, msg, len, flags, to, tolen)
D0 D0 A0 D1 D2 A1 D3
int send(int, char *, int, int, struct sockaddr *, int);
FUNCTION
s is a socket created with socket(). send() and sendto() are
used totransmit a message to another socket. send() may be
used only when the socket is in a connected state, while
sendto()may be used at any time.
The address of the target is given by to with tolen specify-
ing its size. The length of the message is given by len. If
the message is too long to pass atomically through the
underlying protocol, then the error EMSGSIZE is returned, and
the message is not transmitted.
No indication of failure to deliver is implicit in a send().
Return values of -1 indicate some locally detected errors.
If no buffer space is available at the socket to hold the
message to be transmitted, then send() normally blocks,
unless the socket has been placed in non-blocking I/O mode.
The select() call may be used to determine when it is pos-
sible tosend more data.
The flagsparameter is formed by ORing one or more of the
following:
MSG_OOB - Send ``out-of-band'' data on sockets
that support this notion. The underly-
ing protocol must also support ``out-
of-band'' data. Currently, only
SOCK_STREAM sockets created in the
AF_INET address family support out-of-
band data.
System Manual AmiTCP/IP Section B.1 151
MSG_DONTROUTE - The SO_DONTROUTE optionis turned on for
the duration of the operation. This is
usually used only by diagnostic or rout-
ing programs.
RETURN VALUES
On success, these functions return the number of bytes sent.
On failure, they return -1 and set errno to indicate the
error.
ERRORS
EBADF -s is an invalid descriptor.
EINTR -The operation was interrupted by a break
signal.
EINVAL - len is not the size of a valid address
for the specified address family.
EMSGSIZE - The socket requires that message be sent
atomically, and the size of the message
to be sent made this impossible.
ENOBUFS - The system was unable to allocate an
internal buffer. The operation may
succeed when buffers become available.
ENOBUFS - The output queue for a network interface
was full. This generally indicates that
the interface has stopped sending, but
may be caused by transient congestion.
EWOULDBLOCK - The socket is marked non-blocking and
the requested operation would block.
SEE ALSO
connect(), getsockopt(), recv(), select(), socket()
152 Section B.1 AmiTCP/IP System Manual
B.1.14 shutdown()
NAME
shutdown- shut down part of a full-duplex connection
SYNOPSIS
success =shutdown(s, how)
D0 D0 D1
long shutdown(long, long);
DESCRIPTION
The shutdown() call causes all or part of a full-duplex con-
nection on the socket associated with s to be shut down. If
how is 0,then further receives will be disallowed. If how
is 1, then further sends will be disallowed. If how is 2,
then further sends and receives will be disallowed.
RETURN VALUES
0 - on success.
-1 - on failure and sets errno to indicate the error.
ERRORS
EBADF - s is not a valid descriptor.
ENOTCONN - The specified socket is not connected.
SEE ALSO
connect(), socket()
BUGS
The how values should be defined constants.
System Manual AmiTCP/IP Section B.1 153
B.1.15 socket()
NAME
socket -create an endpoint for communication
SYNOPSIS
#include <sys/types.h>
#include <sys/socket.h>
s = socket(domain, type, protocol)
D0 D0 D1 D2
long socket(long, long, long);
FUNCTION
socket()creates an endpoint for communication and returns a
descriptor.
The domain parameter specifies a communications domain
within which communication will take place; this selects the
protocol family which should be used. The protocol family
generally is the same as the address family for the
addressessupplied in later operations on the socket. These
families are defined in the include file <sys/socket.h>.
The currently understood formats are
PF_INET - (ARPA Internet protocols)
The socket has the indicated type, which specifies the
semanticsof communication. Currently defined types are:
SOCK_STREAM
SOCK_DGRAM
SOCK_RAW
A SOCK_STREAM type provides sequenced, reliable, two-way
connection based byte streams. An out-of-band data
transmission mechanism may be supported. A SOCK_DGRAM
socket supports datagrams (connectionless, unreliable mes-
sages of a fixed (typically small) maximum length).
SOCK_RAW sockets provide access to internal network
interfaces.
The protocol specifies a particular protocol to be used with
the socket. Normally only a single protocol exists to sup-
port a particular socket type within a given protocol fam-
ily. However, it is possible that many protocols may exist,
in whichcase a particular protocol must be specified in
this manner. The protocol number to use is particular to
the "communication domain" in which communication is to take
place.
154 Section B.1 AmiTCP/IP System Manual
Sockets of type SOCK_STREAM are full-duplex byte streams,
similar to pipes. A streamsocket must be in a connected
state before any data may be sent or received on it. A con-
nection to another socket is created with a connect() call.
Once connected, data may be transferred using send() and
recv() or their variant calls. When a session has been
completeda CloseSocket() may be performed. Out-of-band
data mayalso be transmitted as described in send() and
receivedas described in recv().
The communications protocols used to implement a SOCK_STREAM
insure that data is not lost or duplicated. If a piece of
data for which the peer protocol has buffer space cannot be
successfully transmitted within a reasonable length of time,
then the connection is considered broken and calls will
indicatean error with -1 returns and with ETIMEDOUT as the
specificerror code (see Errno()). The protocols optionally
keep sockets "warm" by forcing transmissions roughly every
minute inthe absence of other activity.
SOCK_DGRAM and SOCK_RAW sockets allow sending of datagrams
to correspondents named in send() calls. Datagrams are
generally received with recv(), which returns the next
datagramwith its return address.
The operation of sockets is controlled by socket level
options. These options aredefined in the file socket.h.
getsockopt() and setsockopt() are used to get and set
options, respectively.
RETURN VALUES
socket()returns a non-negative descriptor on success. On
failure,it returns -1 and sets errno to indicate the error.
ERRORS
EACCES - Permission to create a socket of the
specified type and/or protocol is
denied.
EMFILE - The per-process descriptor table is
full.
ENOBUFS - Insufficient buffer space is available.
The socket cannot be created until suf-
ficient resources are freed.
EPROTONOSUPPORT - The protocol type or the specified pro-
tocol is not supported within this
domain.
System Manual AmiTCP/IP Section B.1 155
EPROTOTYPE - The protocol is the wrong type for the
socket.
SEE ALSO
accept(),bind(), CloseSocket(), connect(), getsockname(),
getsockopt(), IoctlSocket(), listen(), recv(), select(),
send(), shutdown(), WaitSelect()
156 Section B.2 AmiTCP/IP System Manual
B.2 Other BSD Functions Related to Sockets
B.2.1 getdtablesize()
NAME
getdtablesize - get socket descriptor table size
SYNOPSIS
nfds = getdtablesize()
D0
long getdtablesize(void);
FUNCTION
Return value of maximum number of open socket descriptors.
Larger socket descriptor table can be allocated with
SetDTableSize() call.
SEE ALSO
SetDTableSize()
System Manual AmiTCP/IP Section B.2 157
B.2.2 Syslog()
NAME
syslog -write message to AmiTCP/IP log.
SYNOPSIS
#include <syslog.h>
void syslog(unsigned long level, char * format, ...);
Syslog(level, format, ap)
D0 A0 A1
VOID Syslog(unsigned long, const char *, va_list);
FUNCTION
Writes the message given as format string and arguments
(printf-style) both to the log file and to the console,
execpt ifthe level is LOG_EMERG, which is used by panic(),
in whichcase only the log file is used since panic()
generatesa User Request.
The levelis selected from an ordered list:
LOG_EMERG A panic condition.
LOG_ALERT A condition thatshould be
corrected immediately, such as a
corrupted system database.
LOG_CRIT Critical conditions, such as hard
device errors.
LOG_ERR Errors.
LOG_WARNING Warning messages.
LOG_NOTICE Conditions that are not error con-
ditions, butthat may require spe-
cial handling.
LOG_INFO Informational messages.
LOG_DEBUG Messages that contain information
normally of use only when debugging
a program.
INPUTS
Level - indicates the type of the message. The levels
are defined in sys/syslog.h and listed above.
158 Section B.2 AmiTCP/IP System Manual
format - This is a printf-style format string as defined
in exec.library/RawDoFmt().
arguments- as in printf().
ap - pointer to an array of arguments.
RESULT
Returns no value.
EXAMPLES
To log a message at priority LOG_INFO, it would make the
followingcall to syslog:
syslog(LOG_INFO, "Connection from host %s",
CallingHost);
NOTES
As Exec RawDoFmt() used to do formatting expects by default
short (16bit long) integers you should use the `l'-modifier
when appopriate. See your compiler documentation about how
it passesarguments on a vararg list.
This function is callable from interrupts.
BUGS
Because there is a limited number of internal messages used
by the logging system, some log messages may get lost if a
high priority task or interrupt handler sends many messages
in succession. If this happens, the next log message tells
the fact.
SEE ALSO
exec.library/RawDoFmt()
System Manual AmiTCP/IP Section B.3 159
B.3 Network Data and Address Manipulation
B.3.1 inet _addr()
NAME
inet_addr, inet_network, Inet_MakeAddr, Inet_LnaOf,
Inet_NetOf, Inet_NtoA - Internet address manipulation
inet_makeaddr, inet_lnaof, inet_netof,
inet_ntoa-- inline/stub functions to handle structure arguments
SYNOPSIS
#include <netinet/in.h>
addr = inet_addr(cp)
D0 A0
unsignedlong inet_addr(char *);
net = inet_network(cp)
D0 A0
unsignedlong inet_network(char *);
in_addr =Inet_MakeAddr(net, lna)
D0 D0 D1
unsignedlong Inet_MakeAddr(long, long);
lna = Inet_LnaOf(in)
D0 D0
long Inet_LnaOf(unsigned long);
net = Inet_NetOf(in)
D0 D0
long Inet_NetOf(unsigned long);
addr = Inet_NtoA(in)
DO D0
char * Inet_NtoA(unsigned long);
in_addr =inet_makeaddr(net, lna)
struct in_addr inet_makeaddr(long, long);
lna = inet_lnaof(in)
160 Section B.3 AmiTCP/IP System Manual
int inet_lnaof(struct in_addr);
net = inet_netof(in)
int inet_netof(struct in_addr);
addr = inet_ntoa(in)
char * inet_ntoa(struct in_addr);
IMPLEMENTATION NOTE
Return value of Inet_MakeAddr() and argument types of
Inet_LnaOf(), Inet_NetOf() and Inet_NtoA() are longs instead
of struct in_addr. The original behaviour is achieved by
using included stub functions (lower case function names)
which handle structure arguments.
DESCRIPTION
The routines inet_addr() and inet_network() each interpret
character strings representing numbers expressed in the
Internetstandard `.' notation, returning numbers suitable
for use as Internet addresses and Internet network numbers,
respectively. The routine inet_makeaddr() takes an Internet
network number and a local network address and constructs an
Internetaddress from it. The routines inet_netof() and
inet_lnaof() break apart Internet host addresses, returning
the network number and local network address part, respec-
tively.
The routine inet_ntoa() returns a pointer to a string in the
base 256notation ``d.d.d.d'' described below.
All Internet address are returned in network order (bytes
ordered from left to right). All network numbers and local
address parts are returned as machine format integer values.
INTERNET ADDRESSES
Values specified using the `.' notation take one of the
following forms:
a.b.c.d
a.b.c
a.b
a
When fourparts are specified, each is interpreted as a byte
of data and assigned, from left to right, to the four bytes
of an Internet address. Note: when an Internet address is
viewed as a 32-bit integer quantity on little endian
systems, the bytes referred to above appear as d.c.b.a.
System Manual AmiTCP/IP Section B.3 161
bytes areordered from right to left.
When a three part address is specified, the last part is
interpreted as a 16-bit quantity and placed in the right
most twobytes of the network address. This makes the three
part address format convenient for specifying Class B net-
work addresses as "128.net.host".
When a two part address is supplied, the last part is inter-
preted as a 24-bit quantity and placed in the right most
three bytes of the network address. This makes the two part
address format convenient for specifying Class A network
addressesas "net.host".
When onlyone part is given, the value is stored directly in
the network address without any byte rearrangement.
All numbers supplied as ``parts'' in a `.' notation may be
decimal, octal, or hexadecimal, as specified in the C
language(that is, a leading 0x or 0X implies hexadecimal;
otherwise, a leading0 implies octal; otherwise, the number
is interpreted as decimal).
RETURN VALUE
The value-1 is returned by inet_addr() and inet_network()
for malformed requests.
BUGS
The problem of host byte ordering versus network byte order-
ing is confusing. A simple way to specify Class C network
addressesin a manner similar to that for Class B and Class
A is needed.
The return value from inet_ntoa() points to static buffer
which is overwritten in each inet_ntoa() call.
162 Section B.4 AmiTCP/IP System Manual
B.4 Network, Protocol and Service Queries
B.4.1 gethostbyname()
NAME
gethostbyname, gethostbyaddr - get network host entry
SYNOPSIS
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
hostent =gethostbyname(name)
D0 A0
struct hostent *gethostbyname(char *);
hostent =gethostbyaddr(addr, len, type)
D0 A0 D0 D1
struct hostent *gethostbyaddr(caddr_t, LONG, LONG);
DESCRIPTION
gethostbyname() and gethostbyaddr() both return a pointer
to an object with the following structure containing the
data received from a name server or the broken-out fields
of a linein netdb configuration file. In the case of
gethostbyaddr(), addr is a pointer to the binary format
address of length len (not a character string) and type is
an address family as defined in <sys/socket.h>.
struct hostent -
char *h_name; /* official name of host */
char **h_aliases; /* alias list */
int h_addrtype; /* address type */
int h_length; /* length of address */
char **h_addr_list; /* list of addresses from name server */
";
The members of this structure are:
h_name Official name of the host.
h_aliases A zero terminated array of alternate
names for the host.
h_addrtype The type of address being returned;
currently always AF_INET.
h_length The length, in bytes, of the address.
System Manual AmiTCP/IP Section B.4 163
h_addr_list A pointer to a list of network addresses
for the named host. Host addresses are
returned in network byte order.
DIAGNOSTICS
A NULL pointer is returned if no matching entry was found or
error occured.
BUGS
All information is contained in a static area so it must be
copied ifit is to be saved. Only the Internet address for-
mat is currently understood.
SEE ALSO
AmiTCP/IP configuration
164 Section B.4 AmiTCP/IP System Manual
B.4.2 getnetbyname()
NAME
getnetbyname, getnetbyaddr - get network entry
SYNOPSIS
#include <netdb.h>
netent =getnetbyname(name)
D0 A0
struct netent *getnetbyname(char *);
netent =getnetbyaddr(net, type)
D0 D0 D1
struct netent *getnetbyaddr(long, long);
DESCRIPTION
getnetbyname(), and getnetbyaddr() both return a pointer to
an object with the following structure containing the
broken-out fields of a line in netdb configuration file.
struct netent -
char *n_name; /* official name of net */
char **n_aliases; /* alias list */
int n_addrtype; /* net number type */
long n_net; /* net number */
";
The members of this structure are:
n_name The official name of the network.
n_aliases A zero terminated list of alternate
names for the network.
n_addrtype The type of the network number returned;
currently only AF_INET.
n_net The network number. Network numbers are
returned in machine byte order.
Network numbers are supplied in host order.
Type specifies the address type to use, currently only
AF_INET is supported.
DIAGNOSTICS
A NULL pointer is returned if no matching entry was found or
error occured.
System Manual AmiTCP/IP Section B.4 165
BUGS
All information is contained in a static area so it must be
copied ifit is to be saved.
Only Internet network numbers are currently understood.
SEE ALSO
AmiTCP/IP configuration
166 Section B.4 AmiTCP/IP System Manual
B.4.3 getprotobyname()
NAME
getprotobyname, getprotobynumber - get protocol entry
SYNOPSIS
#include <netdb.h>
protoent= getprotobyname(name)
D0 A0
struct protoent *getprotobyname(char *);
protoent= getprotobynumber(proto)
D0 D0
struct protoent *getprotobynumber(long);
DESCRIPTION
getprotobyname() and getprotobynumber() both return a pointer
to an object with the following structure containing the
broken-out fields of a line in netdb configuration file
struct protoent -
char *p_name; /* official name of protocol */
char **p_aliases; /* alias list */
int p_proto; /* protocol number */
";
The members of this structure are:
p_name The official name of the protocol.
p_aliases A zero terminated list of alternate
names for the protocol.
p_proto The protocol number.
DIAGNOSTICS
A NULL pointer is returned if no matching entry was found or
error occured.
BUGS
All information is contained in a static area so it must be
copied if it is to be saved. Only the Internet protocols
are currently understood.
SEE ALSO
AmiTCP/IP configuration
System Manual AmiTCP/IP Section B.4 167
B.4.4 getservbyname()
NAME
getservbyname, getservbyport - get service entry
SYNOPSIS
#include <netdb.h>
servent =getservbyname(name, proto)
D0 A0 A1
struct servent *getservbyname(char *, char *)
servent =getservbyport(port, proto)
D0 D0 A0
struct servent *getservbyport(long, char *);
DESCRIPTION
getservbyname() and getservbyport() both return a pointer to
an object with the following structure containing the
broken-out fields of a line in netdb configuration file.
struct servent -
char *s_name; /* official name of service */
char **s_aliases; /* alias list */
int s_port; /*port service resides at */
char *s_proto; /* protocol to use */
";
The members of this structure are:
s_name The official name of the service.
s_aliases A zero terminated list of alternate
names for the service.
s_port The port number at which the ser-
vice resides. Port numbers are
returned in network short byte
order.
s_proto The name of the protocol to use
when contacting the service.
The protoargument specifies the protocol for which to the
sercive is to use. It is a normal C string, e.g. "tcp" or
"udp".
DIAGNOSTICS
A NULL pointer is returned if no matching entry was found or
error occured.
BUGS
All information is contained in a static area so it must be
168 Section B.4 AmiTCP/IP System Manual
copied if it is to be saved. Expecting port numbers to fit
in a 32 bit quantity is probably naive.
SEE ALSO
AmiTCP/IP configuration
System Manual AmiTCP/IP Section B.5 169
B.5 AmiTCP/IP Specific Extensions
B.5.1 Errno()
NAME
Errno - get error value after unsuccessful function call
SYNOPSIS
errno = Errno()
D0
LONG Errno(VOID);
FUNCTION
When some function in socket library return an error
conditionvalue, they also set a specific error value. This
error value can be extracted by this function.
RESULT
Error value indicating the error on last failure of some
socket function call.
NOTES
Return value of Errno() is not changed after successful
functionso so it cannot be used to determine success of any
functioncall of this library. Also, another function call
to this library may change the return value of Errno() so
use it right after error occurred.
SEE ALSO
SetErrnoPtr()
170 Section B.5 AmiTCP/IP System Manual
B.5.2 ObtainSocket()
NAME
ObtainSocket - get a socket from AmiTCP/IP socket list
SYNOPSIS
s = ObtainSocket(id, domain, type, protocol)
D0 D0 D1 D2 D3
LONG ObtainSocket(LONG, LONG, LONG, LONG);
FUNCTION
When onetask wants to give a socket to an another one, it
releasesit (with a key value) to a special socket list held
by AmiTCP/IP. This function requests that socket and
receivesit if id and other parameters match.
INPUTS
id - a key value given by the socket donator.
domain - see documentation of socket().
type - see documentation of socket().
protocol- see documentation of socket().
RESULT
Non negative socket descriptor on success. On failure, -1 is
returnedand the errno is set to indicate the error.
ERRORS
EMFILE - The per-process descriptor table is
full.
EPROTONOSUPPORT - The protocol type or the specified pro-
tocol is not supported within this
domain.
EPROTOTYPE - The protocol is the wrong type for the
socket.
EWOULDBLOCK - Matching socket is not found.
SEE ALSO
ReleaseCopyOfSocket(), ReleaseSocket(), socket()
System Manual AmiTCP/IP Section B.5 171
B.5.3 ReleaseCopyOfSocket()
NAME
ReleaseCopyOfSocket - copy given socket to AmiTCP/IP socket list.
SYNOPSIS
id = ReleaseCopyOfSocket(fd, id)
D0 D0 D1
LONG ReleaseCopyOfSocket(LONG, LONG);
FUNCTION
Make a new reference to a given socket (pointed by its descriptor)
and release it to the socket list held by AmiTCP/IP.
INPUTS
fd - descriptor of the socket to release.
id - thekey value to identify use of this socket. It can be
unique or not, depending on its value. If id value is
between 0 and 65535, inclusively, it is considered
nonunique and it can be used as a port number, for
example. If id is greater than 65535 and less than
2^31) it must be unique in currently held sockets in
AmiTCP/IP socket list, Otherwise an error will be
returned and socket is not released. If id ==
UNIQUE_ID (defined in <sys/socket.h>) an unique id will
be generated.
RESULT
id - -1 in case of error and the key value of the socket put
in the list. Most useful when an uniqueid is generated
by this routine.
ERRORS
EINVAL -Requested unique id is already used.
ENOMEM -Needed memory couldn't be allocated.
NOTE
The socket descriptor is not deallocated.
SEE ALSO
ObtainSocket(), ReleaseSocket()
172 Section B.5 AmiTCP/IP System Manual
B.5.4 ReleaseSocket()
NAME
ReleaseSocket - release given socket to AmiTCP/IP socket list.
SYNOPSIS
id = ReleaseSocket(fd, id)
D0 D0 D1
LONG ReleaseSocket(LONG, LONG);
FUNCTION
Release the reference of given socket (via its descriptor)
and movethe socket to the socket list held by AmiTCP/IP.
The socket descriptor is deallocated in this procedure.
INPUTS
fd - descriptor of the socket to release.
id - thekey value to identify use of this socket. It can be
unique or not, depending on its value. If id value is
between 0 and 65535, inclusively, it is considered
nonunique and it can be used as a port number, for
example. If id is greater than 65535 and less than
2^31) it must be unique in currently held sockets in
AmiTCP/IP socket list, Otherwise an error will be
returned and socket is not released. If id ==
UNIQUE_ID (defined in <sys/socket.h>) an unique id will
be generated.
RESULT
id - -1 in case of error and the key value of the socket put
in the list. Most useful when an uniqueid is generated
by this routine.
ERRORS
EINVAL -Requested unique id is already used.
ENOMEM -Needed memory couldn't be allocated.
SEE ALSO
ObtainSocket(), ReleaseCopyOfSocket()
System Manual AmiTCP/IP Section B.5 173
B.5.5 SetDTableSize()
NAME
SetDTableSize - set socket descriptor table size of the base
SYNOPSIS
newsize =SetDTableSize(size)
D0 D0
LONG SetDTableSize(UWORD);
FUNCTION
This function increases the descriptor table size inside
library base so more sockets can be open at the same time.
INPUT
size - the new size of the desctiptor table.
RESULT
newsize -the new size of the descriptor table. Note that
this canbe less than requested if an error occured.
WARNING
If the size of fd_set is not adjusted to store the increased
space needed for new socket descriptors some other memory
will bespilled. Change the value of FD_SETSIZE before
including any socket include files and don't increase
descriptor table to greater than the new value of
FD_SETSIZE.
SEE ALSO
getdtablesize(), select()
174 Section B.5 AmiTCP/IP System Manual
B.5.6 SetErrnoPtr()
NAME
SetErrnoPtr - set new place where the error value will be written
SYNOPSIS
SetErrnoPtr(ptr, size)
A0 D0
VOID SetErrnoPtr(VOID *, UBYTE);
FUNCTION
This functions allows caller to redirect error variable inside
scope of caller task. Usually this is used to make task's
global variable errno as error variable.
INPUTS
ptr - pointer to error variable that isto be modified on
every error condition on this library function.
size - size of the error variable.
EXAMPLE
#include <errno.h>
struct Library;
struct Library * SocketBase = NULL;
int main(void)
-
...
if ((SocketBase = OpenLibrary("bsdsocket.library", 2))
!= NULL) -
SetErrnoPtr(&errno, sizeof(errno));
...
"
"
NOTES
Be sure that this new error variable exists until library base
is finally closed or SetErrnoPtr() is called again for another
variable.
SEE ALSO
Errno()
System Manual AmiTCP/IP Section B.5 175
B.5.7 SetSocketSignals()
NAME
SetSocketSignals - inform AmiTCP/IP of INTR, IO and URG signals
SYNOPSIS
SetSocketSignals(sigintrmask, sigiomask, sigurgmask)
D0 D1 D2
VOID SetSocketSignals(ULONG, ULONG, ULONG);
FUNCTION
SetSocketSignals() tells the AmiTCP/IP which signal masks
corresponds UNIX SIGINT, SIGIO and SIGURG signals to be used
in this implementation. sigintrmask mask is used to
determine which Amiga signals interrupt blocking library
calls. sigio- and sigurgmasks are sent when asynchronous
notification of socket events is done and when out-of-band
data arrives, respectively.
Note that the supplied values write over old ones. If this
functionis used and CTRL-C is still wanted to interrupt the
calls (the default behaviour), the value BREAKF_CTRL_C must
be explicitly given.
SEE ALSO
IoctlSocket(), recv(), send(), WaitSelect()
Appendix C
AmiTCP/IP Network Link Library
This appendix describes the functions located in the net.lib.
Table of Contents
autoinit : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :*
* : : : : : : : : 177
autoinitd : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
* : : : :: : : : 178
charRead : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :*
* : : : : : : : : 179
gethostname : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : *
*: : : : : : : : 181
lineRead : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :*
* : : : : : : : : 182
176
System Manual AmiTCP/IP Section C.1 177
C.1 net.lib Functions
C.1.1 autoinit
NAME
autoinit - SAS C Autoinitialization Functions
SYNOPSIS
_STIopenSockets()
void _STIopenSockets(void)
_STDcloseSockets()
void _STDcloseSockets(void)
FUNCTION
These functions open and close the bsdsocket.library at the
startup and exit of the program, respectively. For a
program to use these functions, it must be linked with
netlib:net.lib.
Ifthe library can be opened, the _STIopenSockets() calls
bsdsocket.library function SetErrnoPtr() to tell the
library the address and the size of the errno variable of
thecalling program.
NOTES
_STIopenSockets() also checks that the system version is at
least 37. It puts up a requester if the bsdsocket.library
isnot found or is of wrong version.
Theautoinitialization and autotermination functions are
features specific to the SAS C6. However, these functions
canbe used with other (ANSI) C compilers, too. Example
follows:
"*at start of main() *"
atexit(_STDcloseSockets);
_STDopenSockets();
BUGS
SEE ALSO
bsdsocket.library/SetErrnoPtr(),
SAS/C 6 User's Guide p. 145 for details of
autoinitialization and autotermination functions.
178 Section C.1 AmiTCP/IP System Manual
C.1.2 autoinitd
NAME
autoinitd - SAS C Autoinitialization Functions for Daemons
SYNOPSIS
void _STIopenSockets(void);
void _STDcloseSockets(void);
long server_socket;
DESCRIPTION
These are SASC autoinitialization functions for internet daemons
started by inetd, Internet super-server. Upon startup, the server
socket is obtained with ObtainSocket() library call. If successful,
thesocket id is stored to the global variable server_socket. If the
socket is not obtainable, the server_socket contains value -1.
Ifthe server_socket is not valid, the server may try to accept() a
newconnection and act as a stand-alone server.
RESULT
server_socket - positive socket id for success or -1 for failure.
NOTES
_STIopenSockets() also checks that the system version is at
least 37. It puts up a requester if the bsdsocket.library
isnot found or is of wrong version.
Theautoinitialization and autotermination functions are
features specific to the SAS C6. However, these functions
canbe used with other (ANSI) C compilers, too. Example
follows:
"*at start of main() *"
atexit(_STDcloseSockets);
_STDopenSockets();
AUTHOR
Jarno Rajahalme, Pekka Pessi,
theAmiTCP/IP Group <amitcp-group@hut.fi>,
Helsinki University of Technology, Finland.
SEE ALSO
serveraccept(), netutil/inetd
System Manual AmiTCP/IP Section C.1 179
C.1.3 charRead
NAME
charRead -- read characters from socket one by one.
SYNOPSIS
initCharRead(rc, fd)
void initCharRead(struct CharRead *, int);
character = charRead(rc)
intcharRead(struct CharRead *);
DESCRIPTION
charRead is a macro package which return characters one by one
from given socket input stream. The socket where data is to be read
isset by calling initCharRead(): rc is the pointer to charread
structure previously allocated. fd is the (socket) descriptor where
reading is to be done.
charRead() returns the next character from input stream or one of
the following:
RC_DO_SELECT (-3) - read input buffer is returned. Do select
before next call if you don't want charread
to block.
RC_EOF (-2) - end-of-file condition has occurred.
RC_ERROR (-1) - there has been an error while filling new
charread buffer. Check the value of Errno()
NOTE
Always use variable of type int to store return value from charRead()
since the numeric value of characters returned may vary between
0 -255 (or even greater). As you may know, -3 equals 253 if of type
unsigned char.
EXAMPLE
/*
* This piece of code shows how to use charread with select()
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <charread.h>
main_loop(int sock)
-
struct CharReadrc;
fd_set readfds;
int c;
initCharRead(&rc, sock);
180 Section C.1 AmiTCP/IP System Manual
FD_ZERO(&readfds);
while(1) -
FD_SET(sock, &readfds);
if (select(sock + 1. &readfds, NULL, NULL, NULL)) < 0) -
perror("select");
break;
"
if (FD_ISSET(sock, &readfds)) -
while((c = charRead(&rc)) >= 0)
handle_next_input_character(c);
if (c == RC_EOF)
break;
if (c == RC_ERROR) -
perror("charRead");
break;
"
"
"
"
PORTABILITY
Thesource file charread.h should be able to be used in
UNIX programs as is.
AUTHORS
Tomi Ollila,
theAmiTCP/IP Group <amitcp-group@hut.fi>,
SEE ALSO
lineRead(), bsdsocket.library/recv()
System Manual AmiTCP/IP Section C.1 181
C.1.4 gethostname
NAME
gethostname -- get the name of the host
SYNOPSIS
error = gethostname(name, namelen);
intgethostname(char *, int);
FUNCTION
Getthe name of the host to the buffer name of length namelen.
Thename is taken from the environment variable "HOSTNAME"
where it SHOULD reside.
INPUTS
name - Pointer to the buffer where the name should be
stored.
namelen - Length of the buffer name.
RESULT
error - 0 on success,-1 in case of an error. The global
variable errno will be set to indicate the error as
follows:
ENOENT - The environment variable "HOSTNAME" is not
found.
EXAMPLE
char hostname[MAXHOSTNAMELEN];
int error;
error = gethostname(hostname, sizeof(hostname));
if(error < 0)
exit(10);
printf("My name is ""%s""."n", hostname);
NOTES
This function is included for source compatibility with Unix
systems.
TheENOENT errno value is AmiTCP/IP addition.
BUGS
Unlike the Unix version, this version assures that the
resulting string is always NULL-terminated.
SEE ALSO
getenv()
182 Section C.1 AmiTCP/IP System Manual
C.1.5 lineRead
NAME
lineRead -- read newline terminated strings from socket
SYNOPSIS
initLineRead(rl, fd, lftype, bufsize)
void initLineRead(struct LineRead *, int, int, int);
length = lineRead(rl)
intlineread(struct LineRead *);
DESCRIPTION
lineRead() reads newline terminated strings from given descriptor
very efficiently. All the options needed are set by calling
initLineRead(): rl is the pointer to lineread structure previously
allocated. fd is the (socket) descriptor where reading is to be
done. lftype can have following 3 values:
RL_LFNOTREQ - Newline terminated strings are returned unless
there is no newlines left in currently buffered
input. In this case remaining buffer is returned.
RL_LFREQLF - If there is no newlines left in currently buffered
input the remaining input datais copied at the
start of buffer. Caller is informed that next
call will fill the buffer (andit may block).
Lines are always returned withnewline at the end
unless the string is longer than whole buffer.
RL_LFREQNUL - Like LF_REQLF, but remaining newline is removed.
Note here that lenght is one longer that actual
string length since line that has only one
newline at the end would returnlength as 0
which indigate string incomplete condition.
bufsize is used to tell lineread how big the receive buffer is.
always put RL_BUFSIZE here since that value is used to determine
thememory allocated for the buffer. This option is given to you
soyou may decide to use different buffer size than the default
1024.
lineRead() returns the newline terminated string in rl_line field
oflineread structure. Return values of lineRead() are:
1 - RL_BUFSIZE - normal length of returned string.
0 - If zero is returned just after select(),
end-of-file condition has occurred.
Otherwise string is not completed yet.
Make sure you call select() (or use non-
blocking IO) if you don't want next call
System Manual AmiTCP/IP Section C.1 183
to block.
-1 - if rl_Line field of lineread structure
is NULL, it indicates error condition.
If rl_Line points to start of string
buffer, input string has been longer
than buffer. In this case rl_Line points
to zero terminated string of length
RL_BUFSIZE.
Youmay modify the zero terminated string returned by lineRead() in
anyway, but memory around the string is private lineread memory.
EXAMPLE
/*
* The following code shows how to use lineread with select()
*/
#ifdef USE_LOW_MEMORY_BUFFER
#define RL_BUFSIZE 256
#endif
#include <sys/types.h>
#ifdef AMIGA
#include <bsdsocket.h>
#endif
#include <lineread.h>
#define NULL 0
...
main_loop(int sock)
-
struct LineRead* rl;
int length;
fd_set reafdfs;
if (rl = (struct LineRead *)AllocMem(sizeof (*rl), 0)) -
initLineRead(rl, sock, LF_REQLF, RL_BUFSIZE);
FD_ZERO(&readfds);
while(1) -
FD_SET(sock, &readfds);
if (select(sock + 1, &readfds, NULL, NULL, NULL)) < 0) -
perror("select");
break;
"
if (FD_ISSET(sock, &readfds))
if ((length = lineRead(rl)) == 0) /* EOF */
break;
do -
if (length > 0)
184 Section C.1 AmiTCP/IP System Manual
write(1, rl->rl_Line, length); /* stdout. write() for */
/* speed demonstration*/
else - /* length == -1 */
if (rl->rl_Line == NULL); -
perror("lineRead");
break;
"
else -
fprintf(stderr, "lineread input buffer overflow!"n");
write(1, rl->rl_Line, RL_BUFSIZE);
write(1, ""n", 1);
"
"
" while ((length = lineRead(rl)) != 0); /* 0 -> doselect() */
"
FreeMem(rl, sizeof (*rl);
"
else
fprintf("AllocMem: Out Of memory"n");
"
PORTABILITY
Thesource modules lineread.c and lineread.h should compile
inUNIX machines as is.
AUTHORS
Tomi Ollila,
theAmiTCP/IP Group <amitcp-group@hut.fi>,
SEE ALSO
readChar(), bsdsocket.library/recv()
Appendix D
Protocols and Network Interfaces
The AutoDoc file protocol.doc contains on-line manual pages for protocols
and network interfaces.
Table of Contents
arp : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : : *
*: : : : : : : : : : 186
icmp : : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : : :*
* : : : : : : : : : 189
if : : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : *
*: : : : : : : : : : 190
inet : : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : : :*
* : : : : : : : : : 193
ip : : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : *
*: : : : : : : : : : 196
lo : : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : *
*: : : : : : : : : : 198
routing : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : *
*: : : : : : : : : 199
tcp : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : : *
*: : : : : : : : : : 201
udp : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : : *
*: : : : : : : : : : 203
185
186 Section D.1 AmiTCP/IP System Manual
D.1 Protocols and Network Interfaces
D.1.1 arp
NAME
arp- Address Resolution Protocol
CONFIG
AnySANA-II device driver using ARP
SYNOPSIS
#include <sys/socket.h>
#include <net/if_arp.h>
#include <netinet/in.h>
s =socket(AF_INET, SOCK_DGRAM, 0);
DESCRIPTION
ARPis a protocol used to dynamically map between Internet
Protocol (IP) and hardware addresses. It can be used by most
theSANA-II network interface drivers. The current
implementation supports only Internet Protocol (and is tested
only with Ethernet). However, ARP is not limited to only that
combination.
ARPcaches IP-to-hardware address mappings. When an interface
requests a mapping for an address not in the cache, ARP queues
themessage which requires the mapping and broadcasts a
message on the associated network requesting the address
mapping. If a response is provided, the new mapping is cached
andany pending message is transmitted. ARP will queue at most
onepacket while waiting for a mapping request to be responded
to;only the most recently transmitted packet is kept.
Theaddress mapping caches are separate for each interface. The
amount of mappings in the cache may be specified with an
IoctlSocket() request.
Tofacilitate communications with systems which do not use ARP,
IoctlSocket() requests are provided to enter and delete entries
inthe IP-to-Ethernet tables.
USAGE
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/if_arp.h>
struct arpreq arpreq;
IoctlSocket(s, SIOCSARP, (caddr_t)&arpreq);
IoctlSocket(s, SIOCGARP, (caddr_t)&arpreq);
IoctlSocket(s, SIOCDARP, (caddr_t)&arpreq);
These three IoctlSocket()s take the same structure as an argument.
System Manual AmiTCP/IP Section D.1 187
SIOCSARP sets an ARP entry, SIOCGARP gets an ARP entry, and SIOCDARP
deletes an ARP entry. These IoctlSocket() requests may be applied to
anysocket descriptor (s). The arpreq structure contains:
/*Maximum number of octets in protocol/hw address */
#define MAXADDRARP 16
/*
* ARP ioctl request.
*/
struct arpreq -
struct sockaddr arp_pa; /* protocol address */
struct - /* hardware address */
u_char sa_len; /* actual length + 2 */
u_char sa_family;
char sa_data[MAXADDRARP];
" arp_ha;
int arp_flags; /* flags */
";
/* arp_flags andat_flags field values */
#define ATF_INUSE 0x01 /* entry in use */
#define ATF_COM 0x02 /* completed entry */
#define ATF_PERM 0x04 /* permanent entry */
#define ATF_PUBL 0x08 /* publish entry */
Theinterface whose ARP table is manipulated is specified by
arp_pa sockaddr. The address family for the arp_pa sockaddr
must be AF_INET; for the arp_ha sockaddr it must be AF_UNSPEC.
Thelength of arp_ha must match the length of used hardware
address. Maximum length for the hardware address is MAXADDRARP
bytes. The only flag bits which may be written are ATF_PERM
andATF_PUBL. ATF_PERM makes the entry permanent if the
IoctlSocket() call succeeds. ATF_PUBL specifies that the ARP
code should respond to ARP requests for the indicated host
coming from other machines. This allows a host to act as an
ARPserver which may be useful in convincing an ARP-only
machine to talk to a non-ARP machine.
UNSUPPORTED IN AmiTCP/IP
AmiTCP/IP EXTENSIONS
There is an extension to the standard BSD4.4 ARP ioctl interface to
access the contents of the whole ARP mapping cache. (In the BSD4.4
thestatic ARP table is accessed via the /dev/kmem.) The SIOCGARPT
ioctl takes the following arptabreq structure as an argument:
/*
* An AmiTCP/IP specific ARP table ioctl request
*/
struct arptabreq -
struct arpreq atr_arpreq; /* To identify the interface */
long atr_size; /* # of elements in atr_table */
long atr_inuse; /* # of elements in use */
188 Section D.1 AmiTCP/IP System Manual
struct arpreq *atr_table;
";
Theatr_arpreq specifies the used interface. The hardware address
forthe interface is returned in the arp_ha field of atr_arpreq
structure.
TheSIOCGARPT ioctl reads at most atr_size entries from the cache
into the user supplied buffer atr_table, if it is not NULL. Actual
amount of returned entries is returned in atr_size. The current
amount of cached mappings is returned in the atr_inuse.
TheSIOCGARPT ioctl has following usage:
struct arpreq cache[N];
struct arptabreq arptab = - N, 0, cache ";
IoctlSocket(s, SIOCGARPT, (caddr_t)&arptabreq);
DIAGNOSTICS
ARPwatches passively for hosts impersonating the local host
(that is, a host which responds to an ARP mapping request
forthe local host's address).
"duplicate IP address a.b.c.d!!"
"sent from hardware address: %x:%x:...:%x:%x"
ARP has discovered another host on the local network
which responds to mapping requests for its own Internet
address.
BUGS
TheARP is tested only with Ethernet. Other network hardware may
require special ifconfig configuration.
SEE ALSO
inet, netutil/arp, netutil/ifconfig, <net/if_arp.h>
Plummer, Dave, ``An Ethernet Address Resolution Protocol
-or- ConvertingNetwork Protocol Addresses to 48.bit Ether-
netAddresses for Transmission on Ethernet Hardware,'' RFC
826, Network Information Center, SRI International, Menlo
Park, Calif., November 1982. (Sun 800-1059-10)
System Manual AmiTCP/IP Section D.1 189
D.1.2 icmp
NAME
icmp - Internet Control Message Protocol
SYNOPSIS
#include <sys/socket.h>
#include <netinet/in.h>
int
socket(AF_INET, SOCK_RAW, proto)
DESCRIPTION
ICMP is the error and control message protocol used by IP and the
Internet protocol family. It may be accessed through a ``raw
socket'' for network monitoring and diagnostic functions. The proto
parameter to the socket call to create an ICMP socket is obtained
from getprotobyname(). ICMP sockets are connectionless, and are
normally used with the sendto() and recvfrom() calls, though the
connect() call may also be used to fix the destination for future
packets (in which case the recv() and send() socket library calls
maybe used).
Outgoing packets automatically have an IP header prepended to them
(based on the destination address). Incoming packets are received
with the IP header and options intact.
DIAGNOSTICS
A socket operation may fail with one of the following errors
returned:
[EISCONN] when trying to establish a connection ona socket
which already has one, orwhen trying to send a
datagram with the destination address specified and
the socket is already connected;
[ENOTCONN] when trying tosend a datagram, but no destination
address is specified, andthe socket hasn't been
connected;
[ENOBUFS] when the system runs out of memory for aninternal
data structure;
[EADDRNOTAVAIL] when an attempt is made to create a socket with a
network address for whichno network interface
exists.
SEE ALSO
bsdsocket.library/send(), bsdsocket.library/recv(), inet, ip
HISTORY
Theicmp protocol is originally from 4.3BSD.
190 Section D.1 AmiTCP/IP System Manual
D.1.3 if
NAME
if- Network Interface to SANA-II devices
DESCRIPTION
Each network interface in the AmiTCP/IP corresponds to a path
through which messages may be sent and received. A network
interface usually has a SANA-II device driver associated with it,
though the loopback interface, "lo", do not. The network interface
inthe AmiTCP/IP (sana_softc) is superset of the BSD Unix network
interface.
When the network interface is first time referenced, AmiTCP/IP tries
toopen the corresponding SANA-II device driver. If successful, a
software interface to the SANA-II device is created. The "network/"
prefix is added to the SANA-II device name, if needed. Once the
interface has acquired its address, it is expected to install a
routing table entry so that messages can be routed through it.
TheSANA-II interfaces must be configured before they will allow
traffic to flow through them. It is done after the interface is
assigned a protocol address with a SIOCSIFADDR ioctl. Some
interfaces may use the protocol address or a part of it as their
hardware address. On interfaces where the network-link layer address
mapping is static, only the network number is taken from the ioctl;
theremainder is found in a hardware specific manner. On interfaces
which provide dynamic network-link layer address mapping facilities
(for example, Ethernets or Arcnets using ARP), the entire address
specified in the ioctl is used.
Thefollowing ioctl calls may be used to manipulate network
interfaces. Unless specified otherwise, the request takes an ifreq
structure as its parameter. This structure has the form
struct ifreq -
char ifr_name[IFNAMSIZ]; /* interface name (eg. "slip.device/0")*/
union -
struct sockaddr ifru_addr;
struct sockaddr ifru_dstaddr;
short ifru_flags;
" ifr_ifru;
#define ifr_addr ifr_ifru.ifru_addr /* address */
#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* end of p-to-p link */
#define ifr_flags ifr_ifru.ifru_flags /* flags */
";
SIOCSIFADDR Set interface address. Following the address
assignment, the ``initialization'' routine for
the interface is called.
SIOCGIFADDR Get interface address.
SIOCSIFDSTADDR Set point to point address for interface.
SIOCGIFDSTADDR Get point to point address for interface.
System Manual AmiTCP/IP Section D.1 191
SIOCSIFFLAGS Set interface flagsfield. If the interface is
marked down, any processes currently routing
packets through the interface are notified.
SIOCGIFFLAGS Get interface flags.
SIOCGIFCONF Get interface configurationlist. This request
takes an ifconf structure(see below) as a
value-result parameter. The ifc_len field should be
initially set to the sizeof the buffer pointed to
by ifc_buf. On return itwill contain the length,
in bytes, of the configuration list.
/*
* Structure used in SIOCGIFCONF request.
* Used toretrieve interface configuration
* for machine (useful for programs which
* must know all networks accessible).
*/
struct ifconf -
int ifc_len; /* size of associated buffer */
union -
caddr_t ifcu_buf;
struct ifreq *ifcu_req;
" ifc_ifcu;
#define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */
#define ifc_req ifc_ifcu.ifcu_req /* array of structures returned */
";
UNSUPPORTED IN AmiTCP/IP
These standard BSD ioctl codes are not currently supported:
SIOCADDMULTI Enable a multicast address for the interface.
SIOCDELMULTI Disable a previouslyset multicast address.
SIOCSPROMISC Toggle promiscuous mode.
AmiTCP/IP EXTENSIONS
Thefollowing ioctls are used to configure protocol and hardware
specific properties of a sana_softc interface. They are used in the
AmiTCP/IP only.
SIOCSSANATAGS Set SANA-II specific properties with a tag list.
SIOCGSANATAGS Get SANA-II specific properties into a
wiretype_parameters structure and a user tag list.
struct wiretype_parameters
-
ULONG wiretype; /* the wiretype of theinterface */
WORD flags; /* iff_flags*/
struct TagItem*tags; /* tag list userprovides */
192 Section D.1 AmiTCP/IP System Manual
";
SEE ALSO
arp, lo, netutil/arp, netutil/ifconfig, <sys/ioctl.h>, <net/if.h>,
<net/sana2tags.h>
System Manual AmiTCP/IP Section D.1 193
D.1.4 inet
NAME
inet - Internet protocol family
SYNOPSIS
#include <sys/types.h>
#include <netinet/in.h>
DESCRIPTION
TheInternet protocol family implements a collection of protocols
which are centered around the Internet Protocol (IP) and which share
a common address format. The Internet family provides protocol
support for the SOCK_STREAM, SOCK_DGRAM, and SOCK_RAW socket types.
PROTOCOLS
TheInternet protocol family is comprised of the Internet Protocol
(IP), the Address Resolution Protocol (ARP), the Internet Control
Message Protocol (ICMP), the Transmission Control Protocol (TCP),
andthe User Datagram Protocol (UDP).
TCPis used to support the SOCK_STREAM abstraction while UDP is used
tosupport the SOCK_DGRAM abstraction; (SEE ALSO tcp, SEE ALSO udp).
A raw interface to IP is available by creating an Internet socket of
type SOCK_RAW; (SEE ALSO ip). ICMP is used by the kernel to handle
andreport errors in protocol processing. It is also accessible to
user programs; (SEE ALSO icmp). ARP is used to translate 32-bit IP
addresses into varying length hardware addresses; (SEE ALSO arp).
The32-bit IP address is divided into network number and host number
parts. It is frequency-encoded; the most significant bit is zero in
Class A addresses, in which the high-order 8 bits are the network
number. Class Baddresses have their high order two bits set to 10
anduse the highorder 16 bits as the network number field. Class C
addresses have a 24-bit network number part of which the high order
three bits are 110. Sites with a cluster of local networks may
chose to use a single network number for the cluster; this is done
byusing subnet addressing. The local (host) portion of the address
isfurther subdivided into subnet number and host number parts.
Within a subnet, each subnet appears to be an individual network;
externally, the entire cluster appears to be a single, uniform
network requiring only a single routing entry. Subnet addressing is
enabled and examined by the following ioctl commands on a datagram
socket in the Internet domain; they have the same form as the
SIOCIFADDR (SEE ALSO if) command.
SIOCSIFNETMASK Set interface network mask. The network mask
defines the network part of the address; ifit
contains more of the address than the address
type would indicate, then subnets are in use.
SIOCGIFNETMASK Get interface network mask.
ADDRESSING
IPaddresses are four byte quantities, stored in network byte order
(the native Amiga byte order)
194 Section D.1 AmiTCP/IP System Manual
Sockets in the Internet protocol family use the following
addressing structure:
struct sockaddr_in -
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
";
Functions in bsdsocket.library are provided to manipulate structures
ofthis form.
Thesin_addr field of the sockaddr_in structure specifies a local or
remote IP address. Each network interface has its own unique IP
address. The special value INADDR_ANY may be used in this field to
effect "wildcard" matching. Given in a bind() call, this value
leaves the local IP address of the socket unspecified, so that the
socket will receive connections or messages directed at any of the
valid IP addresses of the system. This can prove useful when a
process neither knows nor cares what the local IP address is or when
a process wishes to receive requests using all of its network
interfaces. Thesockaddr_in structure given in the bind() call must
specify an in_addr value of either IPADDR_ANY or one of the system's
valid IP addresses. Requests to bind any other address will elicit
theerror EADDRNOTAVAIL. When a connect() call is made for a socket
that has a wildcard local address, the system sets the sin_addr
field of the socket to the IP address of the network interface that
thepackets for that connection are routed via.
Thesin_port field of the sockaddr_in structure specifies a port
number used by TCP or UDP. The local port address specified in a
bind() call is restricted to be greater than IPPORT_RESERVED
(defined in <netinet/in.h>) unless the creating process is running
asthe super-user, providing a space of protected port numbers. In
addition, the local port address must not be in use by any socket of
same address family and type. Requests to bind sockets to port
numbers being used by other sockets return the error EADDRINUSE. If
thelocal port address is specified as 0, then the system picks a
unique port address greater than IPPORT_RESERVED. A unique local
port address is also picked when a socket which is not bound is used
ina connect() or send() call. This allows programs which do not
care which local port number is used to set up TCP connections by
sim- ply calling socket() and then connect(), and to send UDP
datagrams with a socket() call followed by a send() call.
Although this implementation restricts sockets to unique local port
numbers, TCP allows multiple simultaneous connections involving the
same local port number so long as the remote IP addresses or port
numbers are different for each connection. Programs may explicitly
override the socket restriction by setting the SO_REUSEADDR socket
option with setsockopt (see getsockopt()).
SEE ALSO
bsdsocket.library/bind(), bsdsocket.library/connect(),
System Manual AmiTCP/IP Section D.1 195
bsdsocket.library/getsockopt(), bsdsocket.library/IoctlSocket(),
bsdsocket.library/send(), bsdsocket.library/socket(),
bsdsocket.library/gethostent(), bsdsocket.library/getnetent(),
bsdsocket.library/getprotoent(), bsdsocket.library/getservent(),
bsdsocket.library/inet_addr(), arp, icmp, ip, tcp, udp
Network Information Center, DDN Protocol Handbook (3 vols.),
Network Information Center, SRI International, Menlo Park,
Calif., 1985.
A AmiTCP/IP Interprocess Communication Primer
WARNING
TheInternet protocol support is subject to change as the Internet
protocols develop. Users should not depend on details of the
current implementation, but rather the services exported.
196 Section D.1 AmiTCP/IP System Manual
D.1.5 ip
NAME
ip- Internet Protocol
SYNOPSIS
#include <sys/socket.h>
#include <netinet/in.h>
int
socket(AF_INET, SOCK_RAW, proto)
DESCRIPTION
IPis the transport layer protocol used by the Internet protocol
family. Optionsmay be set at the IP level when using higher-level
protocols that are based on IP (such as TCP and UDP). It may also be
accessed through a ``raw socket'' when developing new protocols, or
special purpose applica- tions.
A single generic option is supported at the IP level, IP_OPTIONS,
that may be used to provide IP options to be transmitted in the IP
header of each outgoing packet. Options are set with setsockopt()
andexamined with getsockopt(). The format of IP options to be sent
isthat specified by the IP protocol specification, with one
exception: the list of addresses for Source Route options must
include the first-hop gateway at the beginning of the list of
gateways. The first-hop gateway address will be extracted from the
option list and the size adjusted accordingly before use. IP
options may be used with any socket type in the Internet family.
RawIP sockets are connectionless, and are normally used with the
sendto and recvfrom calls, though the connect() call may also be
used to fix the destination for future packets (in which case the
recv() and send() system calls may be used).
Ifproto is 0, the default protocol IPPROTO_RAW is used for outgoing
packets, and only incoming packets destined for that protocol are
received. If proto is non-zero, that protocol number will be used
onoutgoing packets and to filter incoming packets.
Outgoing packets automatically have an IP header prepended to them
(based on the destination address and the protocol number the socket
iscreated with). Incoming packets are received with IP header and
options intact.
DIAGNOSTICS
A socket operation may fail with one of the following errors
returned:
[EISCONN] when trying to establish a connection ona socket
which already has one, orwhen trying to send a
datagram with the destination address specified and
the socket is already connected;
[ENOTCONN] when trying tosend a datagram, but no destination
address is specified, andthe socket hasn't been
System Manual AmiTCP/IP Section D.1 197
connected;
[ENOBUFS] when the system runs out of memory for aninternal
data structure;
[EADDRNOTAVAIL] when an attempt is made to create a socket with a
network address for whichno network interface
exists.
Thefollowing errors specific to IP may occur when setting or
getting IP options:
[EINVAL] An unknown socket option name was given.
[EINVAL] The IP option field was improperly formed; an
option field was shorterthan the minimum value or
longer than the option buffer provided.
SEE ALSO
bsdsocket.library/getsockopt(), bsdsocket.library/send(),
bsdsocket.library/recv(), icmp, inet
HISTORY
Theip protocol appeared in 4.2BSD.
198 Section D.1 AmiTCP/IP System Manual
D.1.6 lo
NAME
lo- Software Loopback Network Interface
SYNOPSIS
pseudo-device
loop
DESCRIPTION
Theloop interface is a software loopback mechanism which may be
used for performance analysis, software testing, and/or local
communication. There is no SANA-II interface associated with lo.
Aswith other network interfaces, the loopback interface must have
network addresses assigned for each address family with which it is
tobe used. These addresses may be set or changed with the
SIOCSIFADDR ioctl. The loopback interface should be the last
interface configured, as protocols may use the order of
configuration as an indication of priority. The loopback should
never be configured first unless no hardware interfaces exist.
DIAGNOSTICS
"lo%d: can't handle af%d."
Theinterface was handed a message with ad- dresses formatted in an
unsuitable address family; the packet was dropped.
SEE ALSO
inet, if, netutil/ifconfig
BUGS
Older BSD Unix systems enabled the loopback interface
automatically, using a nonstandard Internet address (127.1). Use
ofthat address is now discouraged; a reserved host address for the
local network should be used instead.
System Manual AmiTCP/IP Section D.1 199
D.1.7 routing
NAME
routing - system supporting for local network packet routing
DESCRIPTION
Thenetwork facilities provided general packet routing,
leaving routing table maintenance to applications processes.
A simple set of data structures comprise a ``routing table''
used in selecting the appropriate network interface when
transmitting packets. This table contains a single entry for
each route to a specific network or host. A user process, the
routing daemon, maintains this data base with the aid of two
socket specific ioctl commands, SIOCADDRT and SIOCDELRT.
Thecommands allow the addition and deletion of a single
routing table entry, respectively. Routing table
manipulations may only be carried out by super-user.
A routing table entry has the following form, as defined in
<net/route.h>:
struct rtentry -
u_long rt_hash;
struct sockaddr rt_dst;
struct sockaddr rt_gateway;
short rt_flags;
short rt_refcnt;
u_long rt_use;
struct ifnet *rt_ifp;
";
with rt_flags defined from:
#define RTF_UP 0x1 /* route usable */
#define RTF_GATEWAY 0x2 /* destination is a gateway */
#define RTF_HOST 0x4 /* host entry (net otherwise) */
Routing table entries come in three flavors: for a specific
host, for all hosts on a specific network, for any destination
notmatched by entries of the first two types (a wildcard
route). When the system is booted, each network interface
autoconfigured installs a routing table entry when it wishes
tohave packets sent through it. Normally the interface
specifies the route through it is a ``direct'' connection to
thedestination host or network. If the route is direct, the
transport layer of a protocol family usually requests the
packet be sent to the same host specified in the packet.
Otherwise, the interface may be requested to address the
packet to an entity different from the eventual recipient
(that is, the packet is forwarded).
Routing table entries installed by a user process may not
specify the hash, reference count, use, or interface fields;
these are filled in by the routing routines. If a route is in
usewhen it is deleted (rt_refcnt is non-zero), the resources
associated with it will not be reclaimed until all references
toit are removed.
200 Section D.1 AmiTCP/IP System Manual
Therouting code returns EEXIST if requested to duplicate an
existing entry, ESRCH if requested to delete a non-existent
entry, or ENOBUFS if insufficient resources were available to
install a new route.
Thert_use field contains the number of packets sent along the
route. This value is used to select among multiple routes to
thesame destination. When multiple routes to the same
destination exist, the least used route is selected.
A wildcard routing entry is specified with a zero destination
address value. Wildcard routes are used only when the system
fails to find a route to the destination host and network.
Thecombination of wildcard routes and routing redirects can
provide an economical mechanism for routing traffic.
SEE ALSO
bsdsocket.library/IoctlSocket(), netutil/route
System Manual AmiTCP/IP Section D.1 201
D.1.8 tcp
NAME
tcp- Internet Transmission Control Protocol
SYNOPSIS
#include <sys/socket.h>
#include <netinet/in.h>
int
socket(AF_INET, SOCK_STREAM, 0)
DESCRIPTION
TheTCP protocol provides reliable, flow-controlled, two-way
transmission of data. It is a byte-stream protocol used to support
theSOCK_STREAM abstraction. TCP uses the standard Internet address
format and, in addition, provides a per-host collection of ``port
addresses''. Thus, each address is composed of an Internet address
specifying the host and network, with a specific TCP port on the
host identifying the peer entity.
Sockets utilizing the tcp protocol are either ``active'' or
``passive''. Active sockets initiate connections to passive
sockets. By default TCP sockets are created active; to create a
passive socket the listen() bsdsocket.library function call must be
used after binding the socket with the bind() bsdsocket.library
function call. Only passive sockets may use the accept() call to
accept incoming connections. Only active sockets may use the
connect() call to initiate connections.
Passive sockets may ``underspecify'' their location to match
incoming connection requests from multiple networks. This
technique, termed ``wildcard addressing'', allows a single server to
provide service to clients on multiple networks. To create a socket
which listens on all networks, the Internet address INADDR_ANY must
bebound. The TCP port may still be specified at this time; if the
port is not specified the bsdsocket.library function will assign
one. Once a connection has been established the socket's address is
fixed by the peer entity's location. The address assigned the
socket is the address associated with the network interface through
which packets are being transmitted and received. Normally this
address corresponds to the peer entity's network.
TCPsupports one socket option which is set with setsockopt() and
tested with getsockopt(). Under most circumstances, TCP sends data
when it is presented; when outstanding data has not yet been
acknowledged, it gathers small amounts of output to be sent in a
single packet once an acknowledgement is received. For a small
number of clients, such as X Window System functions that
send a stream of mouse events which receive no replies, this
packetization may cause significant delays. Therefore, TCP provides
a boolean option, TCP_NODELAY (from <netinet/tcp.h>, to defeat this
algorithm. Theoption level for the setsockopt call is the protocol
number for TCP, available from getprotobyname().
Options at the IP transport level may be used with TCP; SEE ALSO ip.
202 Section D.1 AmiTCP/IP System Manual
Incoming connection requests that are source-routed are noted, and
thereverse source route is used in responding.
DIAGNOSTICS
A socket operation may fail with one of the following errors
returned:
[EISCONN] when trying to establish a connection ona socket
which already has one;
[ENOBUFS] when the AmiTCP/IP runs out of memory foran internal
data structure;
[ETIMEDOUT] when a connection was dropped due to excessive
retransmissions;
[ECONNRESET] when the remote peerforces the connection to be
closed;
[ECONNREFUSED] when the remote peer actively refuses connection
establishment (usually because no process is
listening to the port);
[EADDRINUSE] when an attempt is made to create a socket with a
port which has already been allocated;
[EADDRNOTAVAIL] when an attempt is made to create a socket with a
network address for whichno network interface
exists.
SEE ALSO
bsdsocket.library/getsockopt(), bsdsocket.library/socket(),
bsdsocket.library/bind(), bsdsocket.library/listen(),
bsdsocket.library/accept(), bsdsocket.library/connect(), inet,
ip,<sys/socket.h>, <netinet/tcp.h>, <netinet/in.h>
HISTORY
Thetcp protocol stack appeared in 4.2BSD.
System Manual AmiTCP/IP Section D.1 203
D.1.9 udp
NAME
udp- Internet User Datagram Protocol
SYNOPSIS
#include <sys/socket.h>
#include <netinet/in.h>
int
socket(AF_INET, SOCK_DGRAM, 0)
DESCRIPTION
UDPis a simple, unreliable datagram protocol which is used to
support the SOCK_DGRAM abstraction for the Internet protocol family.
UDPsockets are connectionless, and are normally used with the
sendto() and recvfrom() calls, though the connect() call may also be
used to fix the destination for future packets (in which case the
recv() and send() function calls may be used).
UDPaddress formats are identical to those used by TCP. In
particular UDP provides a port identifier in addition to the normal
Internet address format. Note that the UDP port space is separate
from the TCP port space (i.e. a UDP port may not be ``connected'' to
a TCP port). In addition broadcast packets may be sent (assuming the
underlying network supports this) by using a reserved ``broadcast
address''; this address is network interface dependent.
Options at the IP transport level may be used with UDP; SEE ALSO ip.
DIAGNOSTICS
A socket operation may fail with one of the following errors
returned:
[EISCONN] when trying to establish a connection ona socket
which already has one, orwhen trying to send a
datagram with the destination address specified and
the socket is already connected;
[ENOTCONN] when trying tosend a datagram, but no destination
address is specified, andthe socket hasn't been
connected;
[ENOBUFS] when the system runs out of memory for an
internal data structure;
[EADDRINUSE] when an attempt is made to create a socket with a
port which has already been allocated;
[EADDRNOTAVAIL] when an attempt is made to create a socket with a
network address for whichno network interface
exists.
SEE ALSO
bsdsocket.library/getsockopt(), bsdsocket.library/recv(),
bsdsocket.library/send(), bsdsocket.library/socket(), inet, ip
204 Section D.1 AmiTCP/IP System Manual
HISTORY
Theudp protocol appeared in 4.2BSD.